Açısal2 http.get (), harita (), abone olma () ve gözlemlenebilir model - temel anlayış


170

Şimdi, üç bağlantımın olduğu bir başlangıç ​​sayfam var. Son 'arkadaşlar' bağlantısını tıkladığınızda, uygun arkadaşlar Bileşeni başlatılır. Orada, friends.json dosyasına sokulan arkadaşlarımın listesini almak / almak istiyorum. Şimdiye kadar her şey yolunda gidiyor. Ama ben hala RXJs gözlemlenebilir, harita, abone kavramını kullanarak angular2 HTTP hizmeti için bir acemi. Anlamaya çalıştım ve birkaç makale okudum, ancak pratik çalışmaya girene kadar, bu kavramları düzgün bir şekilde anlamayacağım.

Burada zaten HTTP ile ilgili çalışma dışında çalışan plnkr yaptık.

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.

       }
  }

Lütfen doğru şekilde yönlendirin ve açıklayın. Birçok yeni geliştirici için çok faydalı olacağını biliyorum.

Yanıtlar:


205

Yanlış yaptığınız yer:

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

olmalı:

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

veya

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

İki hata yaptınız:

1- sen gözlemlenenin kendisini tayin ettin this.result. Arkadaş listesini gerçekten atamak istediğinizde this.result. Bunu yapmanın doğru yolu:

  • gözlemlenebilir olana abone olursunuz. .subscribegerçekte gözlemlenebilir olanı yerine getiren işlevdir. Aşağıdaki gibi üç geri çağrı parametresi alır:

    .subscribe(success, failure, complete);

Örneğin:

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

Genellikle, sonuçları başarılı geri aramadan alır ve değişkeninize atarsınız. hata geri araması açıklayıcıdır. tam geri arama, son sonuçları hatasız olarak aldığınızı belirlemek için kullanılır. Dalma pistonunuzda, tam geri arama her zaman başarılı veya hata geri aramasından sonra çağrılır.

2- ikinci hata aradığını .json()üzerinde .map(res => res.json())o zaman gözlemlenebilir başarısı Geri aramada tekrar aradı. başarıyı geri aramaya geçmeden önce .map()sonucu geri döndürdüğünüz her şeye dönüştürecek bir transformatördür .json().


2
İşte dalgıçsın . Satırları değiştirdim: 21, 23
myfriends.ts'ta

1
Anlamadığım şey, "harita" işlevini neden burada kullanmaktır? Sonuçta sadece .json'u çağırabiliriz. Peki bunu yapmanın yararı nedir?
rubmz

5
Haklısın @rubmz. Bunu cevabımda bahsettiğim gibi yapabilirsin, ama büyük bir yararı mantığı ayırmak. Örneğin, hizmetinizde bir fonksiyonunuz var getFriends(){return http.get('friends.json').map(r => r.json());}. Artık her seferinde aramanıza getFriends().subscribe(...)gerek kalmadan arayabilirsiniz .json().
Abdulrahman Alsoghayer

2
Evet, bu yeni başlayanlar için biraz kafa karıştırıcı. O gizemli haritanın () yaptığı ve ne olmadığı ... Ama sonunda bunu da aldım :)
rubmz

1
@Abdulrahman, belki de bu soruya bir göz atmak
isteyeceksiniz

138

Kavramlar

Kısa süreli asenkron işleme ve olaylarda gözlemlenebilir. Vaatlerle karşılaştırıldığında, bu gözlemlenebilir = vaat + olaylar olarak tanımlanabilir.

Gözlenebilirler ile harika olan şey, tembel olmaları, iptal edilebilirleri ve bunlara bazı operatörler uygulayabilmenizdir ( map... gibi ). Bu, zaman uyumsuz şeyleri çok esnek bir şekilde ele almayı sağlar.

Gözlenebilirlerin gücünü en iyi açıklayan harika bir örnek, bir filtre girişini karşılık gelen filtrelenmiş bir listeye bağlamanın yoludur. Kullanıcı karakterleri girdiğinde liste yenilenir. Gözlenebilirler, karşılık gelen AJAX isteklerini işler ve girişteki yeni değerle başka bir değer tetiklenirse önceki devam eden istekleri iptal eder. İşte ilgili kod:

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

( textValuefiltre girişi ile ilişkili kontroldür).

İşte bu kullanım örneğinin daha geniş bir açıklaması: Açısal 2'deki form değişikliklerini nasıl izleyebilirim? .

AngularConnect 2015 ve EggHead'de iki harika sunum var:

Christoph Burgdorf da konuyla ilgili bazı harika blog yazıları yazdı:

Eylemde

Aslında kodunuzla ilgili olarak iki yaklaşım karıştırdınız ;-) İşte bunlar:

  • Gözlenebilir olanı kendiniz yönetin . Bu durumda, subscribegözlemlenebilir yöntemdeki yöntemi çağırmak ve sonucu bileşenin bir özelliğine atamaktan sorumlusunuz . Daha sonra bu özniteliği koleksiyon üzerinde yineleme yapmak için kullanabilirsiniz:

    @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();
       }
    }
    

    Her ikisinden elde edilen getiriler getve mapyöntemler sonuç değil gözlemlenebilirdir (vaatlerle aynı şekilde).

  • Gözlenebilen öğeyi Açısal şablonla yönetelim . Ayrıca asyncgözlemlenebilir olanı dolaylı olarak yönetmek için boruyu kullanabilirsiniz. Bu durumda, subscribeyöntemi açıkça çağırmaya gerek yoktur .

    @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());
       }
    }
    

Gözlenebilirlerin tembel olduğunu fark edebilirsiniz. Bu nedenle, karşılık gelen HTTP isteği, yalnızca subscribeyöntemi kullanarak üzerine eklenmiş bir dinleyici çağrıldığında çağrılacaktır .

mapYöntemin JSON içeriğini yanıttan ayıklamak ve daha sonra gözlemlenebilir işlemede kullanmak için kullanıldığını da fark edebilirsiniz .

Umarım bu sana yardımcı olur, Thierry


Tüm referanslarınız için teşekkürler. Ama düşüğümde bana yardım edebilir misin?
nyks

Yanıtımı kodunuzla ilgili daha fazla ayrıntıyla güncelledim. Umarım size yardımcı olur ;-)
Thierry Templier

Seni cevaplayamadığım için üzgünüm. Daha açık ama kabul edilen ve takdir edilen bir yanıt, sorum hakkında yeterince anlamamı sağladı. Ama umarım daha ayrıntılı bir açıklamaya sahip olduğunuz için açık cevabınız için iyi vuruşlar alırsınız. İyi bir temel eksiklik için kabul edilmiş cevap.
micronyks

2
Thierry Templier bu mükemmel bir cevap ama benim için bir şey net değil, http.get ('friends.json') .map (response => response.json ()) gözlemlenebilir <Array <Object>> döndürdü. Evet ise, bunu nasıl gönderirsiniz. Sonuç? farklı tiplerdir.
Stav Alfi

@StavAlfi pipesde bir observables. bu videoyu izleyin: youtube.com/watch?v=bVI5gGTEQ_U daha fazla bilgi için thierry tarafından önerildi.
candidJ

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

HttpClient API 4.3.0 sürümünde tanıtıldı. Mevcut HTTP API'nin bir evrimidir ve kendi paketi @ angular / common / http'dir. En önemli değişikliklerden biri, şimdi yanıt nesnesinin varsayılan olarak bir JSON olmasıdır, bu yüzden artık harita yöntemiyle ayrıştırmaya gerek yoktur.

http.get('friends.json').subscribe(result => this.result =result);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.