简体   繁体   English

Rxjs:将 subject.pipe() 分配给 Angular ngOnInit 中的可观察对象

[英]Rxjs: Assigning a subject.pipe() to an observable in Angular ngOnInit

The template has an input listening to keyUp event.模板有一个监听 keyUp 事件的输入。 The component has an Observable and a Subject.该组件有一个 Observable 和一个 Subject。 The Subject is piped with operators that will map the string value from the input into a Stock[] Observable.主题通过操作符进行管道传输,这些操作符将 map 将字符串值从输入到 Stock[] Observable。 On every keyUp event the Subject emits the next event with a new value from the input.在每个 keyUp 事件上,Subject 都会发出带有来自输入的新值的下一个事件。

template:模板:

<div>
<input  name="searchBox"
        [(ngModel)]="searchString"
        placeholder="Search here"
        (keyup)="search()">
</div>

<h2>
     We have found {{ (stocks$ | async )?.length }} stocks!
</h2>
 <app-stock-item *ngFor="let stock of stocks$ | async"
            [stock]="stock"
>

</app-stock-item>       

component:零件:

import { Component, OnInit } from '@angular/core';
import {Observable} from 'rxjs';
import {StockService} from '../../services/stock.service';
import {Stock} from '../../model/stock';

import {Subject} from 'rxjs';

import {debounceTime,switchMap,distinctUntilChanged,
    startWith, share} from 'rxjs/operators';

@Component({
   selector: 'app-stock-list',
   templateUrl: './stock-list.component.html',
   styleUrls: ['./stock-list.component.css']
})
export class StockListComponent implements OnInit {

  public stocks$!: Observable<Stock[]>;

  public searchString:string = "";

  private searchTerms:Subject<string> = new Subject();

  constructor(private stockService:StockService) { }

  ngOnInit(): void {

  console.log(this.stocks$);

                  // how does this work after ngOnInit is executed?
  this.stocks$ = this.searchTerms.pipe(
                  startWith(this.searchString),
                  debounceTime(500),
                  distinctUntilChanged(),
                  //getStocks returns an Observable of HttpClient
                  switchMap( (query) => this.stockService.getStocks(query)),
                  share()
      );


  }


  search(){

    this.searchTerms.next(this.searchString);

  }

}

If ngOnInit is called only once every rendering of the component, why Subject.pipe() and Subject.next() still works after the ngOnInit finishes its execution?如果每次渲染组件时只调用一次 ngOnInit,为什么在 ngOnInit 完成执行后 Subject.pipe() 和 Subject.next() 仍然有效? does the Subject gets subscribed anywhere in the code?主题是否在代码中的任何位置被订阅?

Very simplified picture is:非常简化的图片是:

searchTerms = {
  subscriptionFn: null,
  next: function(query) {
    this.subscriptionFn(query);
  }
};
stocks$ = {value: null};
    
    
ngOnInit() {
  this.searchTerms.subscriptionFn = (query) => this.stockService.getStocks(query).subscribe(value => this.stocks$.value = value);
}

search(){

  this.searchTerms.next(this.searchString);

}

And html async pipe will be just {{stocks$.value}} .而 html 异步 pipe 将只是{{stocks$.value}} There are lots of differences - eg switchMap will cancel old request, when new raises etc., but ~~~ this code is doing same.有很多不同之处 - 例如 switchMap 将取消旧请求,当新的引发等时,但是~~~这个代码是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM