Angular2 http.get (), map (), subscribe () 및 관찰 가능한 패턴-기본 이해


170

이제 3 개의 링크가있는 초기 페이지가 있습니다. 마지막 '친구'링크를 클릭하면 적절한 친구 구성 요소가 시작됩니다. 거기에서 friends.json 파일로 쓰인 친구 목록을 가져오고 싶습니다. 지금까지 모든 것이 잘 작동합니다. 그러나 나는 여전히 RxJ의 Observable, Map, Subscribe 개념을 사용하는 angular2의 HTTP 서비스에 대한 초보자입니다. 나는 그것을 이해하고 기사를 거의 읽지 않았지만 실제 작업에 들어가기 전에는 그 개념을 제대로 이해하지 못할 것입니다.

여기에 이미 HTTP 관련 작업을 제외하고 작동하는 plnkr을 만들었습니다.

Plnkr

myfriends.ts

 import {Component,View,CORE_DIRECTIVES} from 'angular2/core';
 import {Http, Response,HTTP_PROVIDERS} from 'angular2/http';
 import 'rxjs/Rx';
 @Component({
    template: `
    <h1>My Friends</h1>
    <ul>
      <li *ngFor="#frnd of result">
          {{frnd.name}} is {{frnd.age}} years old.
      </li>
    </ul>
    `,
    directive:[CORE_DIRECTIVES]
  })

  export class FriendsList{

      result:Array<Object>; 
      constructor(http: Http) { 
        console.log("Friends are being called");

       // below code is new for me. So please show me correct way how to do it and please explain about .map and .subscribe functions and observable pattern.

        this.result = http.get('friends.json')
                      .map(response => response.json())
                      .subscribe(result => this.result =result.json());

        //Note : I want to fetch data into result object and display it through ngFor.

       }
  }

올바르게 안내하고 설명하십시오. 많은 새로운 개발자들에게 도움이 될 것입니다.

답변:


205

여기가 잘못되었습니다.

this.result = http.get('friends.json')
                  .map(response => response.json())
                  .subscribe(result => this.result =result.json());

그것은해야한다:

http.get('friends.json')
                  .map(response => response.json())
                  .subscribe(result => this.result =result);

또는

http.get('friends.json')
                  .subscribe(result => this.result =result.json());

두 가지 실수를했습니다.

1- 옵저버 블 자체를에 할당했습니다 this.result. 실제로 친구의 목록을 지정하고 싶어 할 때 this.result. 올바른 방법은 다음과 같습니다.

  • 옵저버 블을 구독합니다. .subscribe실제로 Observable을 실행하는 함수입니다. 다음과 같이 세 가지 콜백 매개 변수가 필요합니다.

    .subscribe(success, failure, complete);

예를 들면 다음과 같습니다.

.subscribe(
    function(response) { console.log("Success Response" + response)},
    function(error) { console.log("Error happened" + error)},
    function() { console.log("the subscription is completed")}
);

일반적으로 성공 콜백에서 결과를 가져 와서 변수에 할당합니다. 오류 콜백은 자명하다. 전체 콜백은 오류없이 마지막 결과를 수신했는지 확인하는 데 사용됩니다. 플 런커에서 성공 또는 오류 콜백 후에 항상 완전한 콜백이 호출됩니다.

2 번째 실수는, 당신은 전화 .json().map(res => res.json())다음 관찰의 성공 콜백에 다시 전화. 성공 콜백으로 전달되기 전에 .map()결과를 반환하는 모든 결과로 변환하는 변환기입니다 ( .json()성공 콜백 중 하나에서 한 번 호출해야 함).


2
여기 당신은 당신의 플 런커 를 이동 합니다 . 나는 myfriends.ts에서 21, 23 행을 바꿨다
Abdulrahman Alsoghayer

1
내가 이해하지 못한 것은 왜 "map"기능을 사용 하는가? 결과에 대해 .json을 호출 할 수 있습니다. 그렇게하면 어떤 이점이 있습니까?
rubmz

5
당신은 바로 @rubmz입니다. 내 대답에서 언급 했듯이이 작업을 수행 할 수 있지만 논리를 분리하면 큰 이점이 있습니다. 예를 들어, 서비스에는 기능이 getFriends(){return http.get('friends.json').map(r => r.json());}있습니다. 이제 매번 getFriends().subscribe(...)전화 .json()할 필요없이 전화 를 걸 수 있습니다 .
Abdulrahman Alsoghayer

2
그렇습니다. 초보자에게는 약간 혼란 스럽습니다. 신비한지도 ()한다는 것을 무엇을하고 무엇을하지 ...하지만 결국 나는 너무 :) 있어요
rubmz

1
@Abdulrahman, 아마 당신은이 질문을
보길 원할 것입니다

138

개념

짧은 관찰 시간은 비동기 처리 및 이벤트를 처리합니다. 약속과 비교하면 이것을 관찰 가능 항목 = 약속 + 이벤트라고 할 수 있습니다.

관찰 가능 항목의 장점은 게으르고 취소 할 수 있으며 일부 연산자 (예 : map, ...)를 적용 할 수 있다는 것 입니다. 이를 통해 매우 유연한 방식으로 비동기식 작업을 처리 할 수 ​​있습니다.

옵저버 블의 최대 성능을 설명하는 훌륭한 샘플은 필터 입력을 해당 필터링 된 목록에 연결하는 방법입니다. 사용자가 문자를 입력하면 목록이 새로 고쳐집니다. Observable은 해당 AJAX 요청을 처리하고 입력에서 새로운 값으로 다른 요청이 트리거되면 이전 진행중인 요청을 취소합니다. 해당 코드는 다음과 같습니다.

this.textValue.valueChanges
    .debounceTime(500)
    .switchMap(data => this.httpService.getListValues(data))
    .subscribe(data => console.log('new list values', data));

( textValue필터 입력과 관련된 컨트롤입니다).

다음은 이러한 사용 사례에 대한보다 자세한 설명입니다. Angular 2에서 양식 변경을 감시하는 방법 .

AngularConnect 2015와 EggHead에는 두 가지 훌륭한 프레젠테이션이 있습니다.

Christoph Burgdorf는 또한이 주제에 관한 훌륭한 블로그 게시물을 작성했습니다.

행동

실제로 코드와 관련하여 두 가지 접근법을 혼합했습니다. ;-) 다음은 다음과 같습니다.

  • 직접 관찰 할 수있는 것을 관리하십시오 . 이 경우, subscribeObservable 에서 메소드 를 호출 하고 결과를 컴포넌트의 속성에 할당해야합니다. 그런 다음 뷰에서이 속성을 사용하여 콜렉션을 반복 할 수 있습니다.

    @Component({
      template: `
        <h1>My Friends</h1>
        <ul>
          <li *ngFor="#frnd of result">
            {{frnd.name}} is {{frnd.age}} years old.
          </li>
        </ul>
      `,
      directive:[CORE_DIRECTIVES]
    })
    export class FriendsList implement OnInit, OnDestroy {
      result:Array<Object>; 
    
      constructor(http: Http) {
      }
    
      ngOnInit() {
        this.friendsObservable = http.get('friends.json')
                      .map(response => response.json())
                      .subscribe(result => this.result = result);
       }
    
       ngOnDestroy() {
         this.friendsObservable.dispose();
       }
    }
    

    getmap메소드 둘 다에서 나온 결과는 결과가 아닌 관찰 가능합니다 (약속과 같은 방식으로).

  • Angular 템플릿으로 Observable을 관리하십시오 . async파이프를 활용 하여 관찰 가능 항목을 암시 적으로 관리 할 수도 있습니다 . 이 경우 subscribe메서드 를 명시 적으로 호출 할 필요가 없습니다 .

    @Component({
      template: `
        <h1>My Friends</h1>
        <ul>
          <li *ngFor="#frnd of (result | async)">
            {{frnd.name}} is {{frnd.age}} years old.
          </li>
        </ul>
      `,
      directive:[CORE_DIRECTIVES]
    })
    export class FriendsList implement OnInit {
      result:Array<Object>; 
    
      constructor(http: Http) {
      }
    
      ngOnInit() {
        this.result = http.get('friends.json')
                      .map(response => response.json());
       }
    }
    

관찰 가능 항목이 게으른 것을 알 수 있습니다. 따라서 해당 HTTP 요청은 subscribe메소드를 사용하여 리스너가 연결된 경우에만 호출 됩니다.

또한 map메소드가 응답에서 JSON 컨텐츠를 추출하고 관찰 가능한 처리에서 사용하는 데 사용됩니다.

티에리가 도움이 되었기를 바랍니다.


모든 참조에 감사드립니다. 근데 내 펑크 좀 도와 줄래?
nyks

코드에 대한 자세한 내용으로 답변을 업데이트했습니다. 그것이 도움이
되기를

답변을받지 못했습니다. 더 명확하지만 인정되고 감사하는 대답은 내 질문에 대해 충분히 이해하는 데 도움이되었습니다. 그러나 더 자세한 설명이 있으면 명확한 답변을 얻을 수 있기를 바랍니다. 좋은 기본 과소 평가에 대한 답변도 받아 들였습니다.
micronyks 12

2
Thierry Templier 이것은 훌륭한 대답이지만 한 가지 분명하지 않습니다. http.get ( 'friends.json') .map (response => response.json ()) observable <Array <Object >>를 반환합니다. 그렇다면 어떻게 보내시겠습니까?. 결과? 그들은 다른 유형입니다.
Stav Alfi

@StavAlfi pipes도 있습니다 observables. 자세한 내용은 thierry가 제안한 youtube.com/watch?v=bVI5gGTEQ_U 비디오를 확인하십시오 .
candidJ

11
import { HttpClientModule } from '@angular/common/http';

HttpClient API는 버전 4.3.0에서 도입되었습니다. 기존 HTTP API의 진화이며 자체 패키지 @ angular / common / http가 있습니다. 가장 주목할만한 변경 사항 중 하나는 이제 응답 객체가 기본적으로 JSON이므로 더 이상 map 메소드로 구문 분석 할 필요가 없다는 것입니다.

http.get('friends.json').subscribe(result => this.result =result);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.