可观察到的管道间隔并作为输入传递,作为异步管道未在模板中呈现

时间:2019-07-10 17:59:47

标签: angular asynchronous input rxjs

说我有一些从某处连续获取的数据;此数据经过处理并通过Input()传递,该输入通过子组件内的异步管道使用-s * ngFor'ed;

可观察的可能是

getObservable(param: string): Observable<string> {
    return timer(1000)
    .pipe(
      map(v => {
        console.log(v);
        return param;
      } )
    )
  }

作为输入传递到子组件列表中

<hello *ngFor="let hi of hellos" [name]="getObservable(hi)"></hello>

这是通过async管道进行管理的Observable

<h1>Hello {{name | async}}!</h1>

https://stackblitz.com/edit/angular-51mxua

  1. 为什么我没有在组件中得到这些数据?
  2. 如何使用这种方法在组件中获取数据(又不更改hello组件,而是在上游修复它,最好不在父组件中存储状态)?

2 个答案:

答案 0 :(得分:3)

这不起作用,因为角度行程变化检测如何。它会不断重复运行getObservable()函数,并取消/取消订阅它,因此它实际上从未达到1000ms超时。

改为执行此操作:

observable$;

constructor() {
  this.observable$ = this.getObservable();
}

并将observable $传递给组件。此更改检测功能也是为什么通常不应将函数调用放在模板中的原因。这是性能危险。

有很多方法可以执行此操作,但是通常您需要确保可观察的分配只运行一次,而模板函数调用不会发生这种情况。

根据您的修改,您可以这样做:

constructor() {
  this.hellos = this.hellos.map(hello => 
                                Object.assign(hello, {observable$: this.getObservable(hello)});
}

<hello *ngFor="let hi of hellos" [name]="hi.observable$"></hello>

您还可以设计一些将函数及其参数传递给子代的系统:

export class HelloComponent implements OnInit  {
  @Input() param: any;
  @Input() fn$: (param: any) => Observable<string>;
  name: Observable<string>;

  ngOnInit() {
    this.name = this.fn$(this.param);
  }
}

在父模板中:

<hello *ngFor="let hi of hellos" [fn$]="getObservable" [param]="hi"></hello>

请警告,如果您的函数使用注入的服务并且您需要绑定上下文,则可能会出现问题。

答案 1 :(得分:0)

您应该这样设置AppComponent:

export class AppComponent  {

  name = 'Angular';
  obs$: Observable<string>;

  constructor() {
    this.obs$ = this.getObservable();
  }

  getObservable(): Observable<string> {
    return timer(1000)
    .pipe(
      map(v => {
        console.log(v);
        return 'this should show right';

      } )
    )
  }

}

和这样的模板:

<hello [name]="obs$"></hello>

请参阅更新的堆叠闪电战:https://stackblitz.com/edit/angular-crvjrf?file=src/app/app.component.html