angular – 为什么组合的observable在使用Subject时不更新模板,或者在ngAfterContentInit之后发出

前端之家收集整理的这篇文章主要介绍了angular – 为什么组合的observable在使用Subject时不更新模板,或者在ngAfterContentInit之后发出前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在组件中定义了一个observable(result $),并通过异步管道在其模板上显示它.可观察量是通过combineLatest的其他2个可观察量(第一个$,第二个$)的组合.
如果其中一个observable或两者都过早发出(在我发现ngAfterContentInit之前),则生成的observable将不会发出值.

组件:不起作用

@Component({
  selector: 'my-app',templateUrl: './app.component.html',styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

result$: Observable<number>;
first$= new Subject<number>();
second$= new Subject<number>();

  constructor() {}

  ngOnInit(){
      this.result$= combineLatest(
        this.first$,this.second$
      ).pipe(
        map(([first,second]) => {
          // This is not printed to the console
          console.log('combined obs emitted value');
          return first + second;
        })
      );
   console.log('first and second emit value');
   this.first$.next(2);
   this.second$.next(4);
  }

  ngAfterContentInit() {
      console.log('ngAfterContentInit');
  }
}

执行顺序是:

1.第一和第二发出价值

2.ngAfterContentInit

我的假设是在ngAfterViewInit中已经渲染了模板并且已经进行了订阅.由于observable在此之前发出值,因此不会通知组件.这只能意味着生成的observable很冷(因此,您需要在它发出值之前进行订阅). 2个观察者是主体,所以我的假设是主体是冷可观察者.它是否正确?

如果我延迟第一个$和第二个$的排放,一切正常:
组件:第一个$和第二个$稍后发出
    @零件({
      选择器:’my-app’,
      templateUrl:’./ app.component.html’,
      styleUrls:[‘./ app.component.css’]
    })
    export class AppComponent {

result$: Observable<number>;
first$= new Subject<number>();
second$= new Subject<number>();

  constructor() {}

  ngOnInit(){

      this.result$= combineLatest(
        this.first$,second]) => {
          console.log('combined obs emitted value');
          return first + second;
        })
      );

    // Solution 1: add timeout
    setTimeout(() => {
      console.log('first and second emit value');
      this.first$.next(2);
      this.second$.next(4);
    })

  }

  ngAfterContentInit() {
      console.log('ngAfterContentInit');
  }
}

订单现在是:

> ngAfterContentInit
>第一和第二发射值
>组合的障碍物排放值

所以,这是因为订阅是在observable发出值之前进行的吗?

如果我将observable更改为BehaviorSubject,即使在订阅发生之前发出值,一切也都有效.这是否意味着BehavIoUrSubjects是热门观察者?
组件:有效

@Component({
  selector: 'my-app',styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

result$: Observable<number>;
first$= new BehaviorSubject<number>(0);
second$= new BehaviorSubject<number>(0);

  constructor() {

  }

  ngOnInit(){

this.result$= combineLatest(
        this.first$,second]) => {
          // This is not printed to the console
          console.log('combined obs emitted value');
          return first + second;
        })
      );


  console.log('first and second emit value');
   this.first$.next(2);
   this.second$.next(4);


  }

  ngAfterContentInit() {
      console.log('ngAfterContentInit');
  }
}

Stackblitz

解决方法

Q1:2个可观察者是主体,所以我的假设是主体是冷可观察者.它是否正确?

A1:answer from this question主题本身很热.这个article描述了热,冷和主题.

Q2:再次,这是因为订阅是在观察者发出价值之前做出的吗?

A2:是的.订阅后,订阅将在您订阅后收到值.你引入的延迟()应该给它时间.

为什么?这是因为BehaviorSubject总是保存一个值并在订阅时发出它,而Subject没有保存值,它只是从生产者发送到当前订阅者的值. Details.

问题3:这是否意味着BehavIoUrSubjects是热门观察者?

答:见A1.

如果这不能直接回答您的问题,请道歉.我只是想说…在处理Subject和BehaviorSubject时,我并不关心它们是热还是冷.

相反,我问:“当我订阅时,我是否希望observable始终保持一个值?”.如果是,我使用BehaviorSubject.如果我在订阅时没有价值,那么主题是可以的.除了这种差异,它们都会在订阅后收到发射值. —取决于你的用例.

猜你在找的Angularjs相关文章