Angular 4でのObservableオブジェクトの典型的な使用

Angular 4のコンポーネントとサービスのObservableオブジェクトの典型的なユースケースを紹介します。



ルーターパラメーターのサブスクライブと別のObservableへのマッピング


タスク: example.com/#/users/42 userIdページを開くと、 userIdでユーザーデータを取得します。


解決策: UserDetailsComponentコンポーネントを初期化するときに、ルーターのパラメーターをサブスクライブします。 つまり、 userIdが変更されると、サブスクリプションがuserIdます。 受信したuserIdを使用して、 userServiceサービスからのユーザーデータでObservableを取得します。


 // UserDetailsComponent ngOnInit() { this.route.params .pluck('userId') //  userId   .switchMap(userId => this.userService.getData(userId)) .subscribe(user => this.user = user); } 




ルーターパラメーターとクエリ文字列のサブスクライブ


タスク: example.com/#/users/42?regionId=13 load(userId, regionId)ページを開くとき、 load(userId, regionId)機能load(userId, regionId)を実行する必要があります。 ルーターからuserIdを取得し、リクエストパラメーターからregionIdを取得します。


解決策:イベントのソースは2つあるため、 Observable.combineLatest関数を使用します。この関数は、各ソースがイベントを生成するときに起動します。


 ngOnInit() { Observable.combineLatest(this.route.params, this.route.queryParams) .subscribe(([params, queryParams]) => { //    const userId = params['userId']; const regionId = queryParams['regionId']; this.load(userId, regionId); }); } 

ルーターに作成されたサブスクリプションは、オブジェクトが破棄されると削除されることに注意してください。角度はこれに従っているため、ルーターのパラメーターのサブスクリプションを解除する必要はありません。


ルーターは、提供するオブザーバブルを管理し、サブスクリプションをローカライズします。 コンポーネントが破壊されると、サブスクリプションはクリーンアップされ、メモリリークから保護されるため、ルートパラメーターObservableからサブスクリプションを解除する必要はありません。 マーク・レイコック

サブスクリプションの終了後にアニメーションの読み込みを停止します


タスク:データの保存を開始した後にダウンロードアイコンを表示し、データの保存時またはエラーが発生したときに非表示にします。


解決策: loading変数はブートローダーの表示を担当し、ボタンをクリックした後、それをtrueに設定しtruefalseに設定するには、 Observable.finally関数false使用します。これらの関数は、サブスクリプションの完了後またはエラーが発生した場合に実行されます。


 save() { this.loading = true; this.userService.save(params) .finally(() => this.loading = false) .subscribe(user => { //   }, error => { //   }); } 

独自のイベントソースを作成する


タスク: configServicelang$変数を作成します。他のコンポーネントは、言語が変更されたときにサブスクライブして応答します。


解決策: BehaviorSubjectクラスを使用してlang$変数を作成します。


BehaviorSubjectSubject 違い


  1. BehaviorSubjectは初期値で初期化する必要があります。
  2. サブスクリプションは、 Subject aの最後の値を返します。
  3. getValue()関数を使用して、最後の値を直接取得できます。

lang$変数を作成し、すぐに初期化します。 また、言語を設定するsetLang関数を追加します。


 // configService lang$: BehaviorSubject<Language> = new BehaviorSubject<Language>(DEFAULT_LANG); setLang(lang: Language) { this.lang$.next(this.currentLang); //    } 

コンポーネントの言語変更にサブスクライブします。 lang$変数は、ホットなObservableオブジェクトです。つまり、オブジェクトが破棄されると、サブスクリプションはサブスクリプションを解除する必要があります。


 private subscriptions: Subscription[] = []; ngOnInit() { const langSub = this.configService.lang$ .subscribe(() => { // ... }); this.subscriptions.push(langSub); } ngOnDestroy() { this.subscriptions .forEach(s => s.unsubscribe()); } 

takeUntilを使用して登録を解除する


特にコンポーネントに3つ以上のサブスクリプションがある場合、 よりエレガントなオプションでサブスクリプションを解除できます。


 private ngUnsubscribe: Subject<void> = new Subject<void>(); ngOnInit() { this.configService.lang$ .takeUntil(this.ngUnsubscribe) //    .subscribe(() => { // ... }); } ngOnDestroy() { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); } 

つまり、ホットサブスクリプションでメモリが失われないように、 ngUnsubscribeの値が変更されるまでコンポーネントはngUnsubscribeます。 そして、ngOnDestroyがngOnDestroyと変更さngOnDestroyます。 このオプションの利点は、各サブスクリプションに1行だけ追加すれば十分であり、サブスクリプションが時間どおりに機能することです。


オートコンプリートまたは検索にObservableを使用する


タスク:フォームにデータを入力するときにページの提案を表示する


解決策:フォームデータを変更するためにサブスクライブし、変更する入力データのみを取得し、イベントが多すぎないように少し遅延させて、Wikipediaにリクエストを送信します。 結果はコンソールに表示されます。 興味深い点は、新しいデータswitchMap場合にswitchMapが以前の要求をキャンセルswitchMapです。 たとえば、最後から2番目のリクエストが2秒間実行され、最後の0.2秒間実行された場合、最後のリクエストの結果がコンソールに表示されます。


 ngOnInit() { this.form.valueChanges .takeUntil(this.ngUnsubscribe) //    .map(form => form['search-input']) //   .distinctUntilChanged() //    .debounceTime(300) //    .switchMap(this.wikipediaSearch) //  Observable     .subscribe(data => console.log(data)); } wikipediaSearch = (text: string) => { return Observable .ajax('https://api.github.com/search/repositories?q=' + text) .map(e => e.response); } 

リクエストのキャッシュ


タスク: Observableリクエストをキャッシュする必要があります。


解決策: publishReplayrefCount束を使用します。 最初の関数は1つの関数値を2秒間キャッシュし、2番目の関数は作成されたサブスクリプションをカウントします。 つまり、すべてのサブスクリプションが完了すると、Observableは終了します。 ここでもっと読むことができます。


 // tagService private tagsCache$ = this.getTags() .publishReplay(1, 2000) //     2  .refCount() //   .take(1); //  1  getCachedTags() { return tagsCache$; } 

シリアルコンバイン


タスク:サーバー上の重大な状況! バックエンドチームは、製品の正しい更新のために厳密に順番に実行する必要があると述べました。


  1. 製品データ(タイトルと説明)の更新。
  2. 製品タグのリストを更新します。
  3. 製品カテゴリのリストを更新します。

解決策: productServiceから派生した3つのObservableがproductServiceます。 concatMapを使用しconcatMap


 const updateProduct$ = this.productService.update(product); const updateTags$ = this.productService.updateTags(productId, tagList); const updateCategories$ = this.productService.updateCategories(productId, categoryList); Observable .from([updateProduct$, updateTags$, updateCategories$]) .concatMap(a => a) //    .toArray() //     .subscribe(res => console.log(res)); // res     

スタッフのなぞなぞ


少し練習したい場合は、前の問題を解決しますが、製品を作成します。 つまり、最初に製品を作成し、次にタグを更新してから、カテゴリのみを更新します。


便利なリンク




Source: https://habr.com/ru/post/J337512/


All Articles