带有 ChangeDetectionStrategy.OnPush 和异步管道的 Angular 2 Observable 不起作用
Posted
技术标签:
【中文标题】带有 ChangeDetectionStrategy.OnPush 和异步管道的 Angular 2 Observable 不起作用【英文标题】:Angular 2 Observable with ChangeDetectionStrategy.OnPush and async pipe are not working 【发布时间】:2016-11-04 19:58:31 【问题描述】:我使用 observable 将列表从服务返回到我的组件,在我的组件中我使用 ChangeDetectionStrategy.OnPush,在模板中我使用异步管道,希望这会带来一些性能优势,因为没有执行更改检测一直都有,但只有在有新内容可用时。
以下是我的服务:
import Injectable, Inject, EventEmitter from '@angular/core';
import Observable from 'rxjs/Observable';
import Subject from 'rxjs/Subject';
@Injectable()
export class ListService
public _list$: Subject<any[]>;
private list: any[] = [];
constructor()
this._list$ = <Subject<any>>new Subject();
get list$()
return this._list$.asObservable();
loadList()
//if this.list is populated through an http call the view is updated,
//if its a static list like below, it doesn't trigger view update.
//this.list = ['Red', 'Green', 'Yellow', 'Blue'];
this._list$.next(this.list);
在我的组件中我有:
import Component, ChangeDetectionStrategy from '@angular/core';
import Observable from 'rxjs/Observable';
@Component(
templateUrl: `
<ul>
<li *ngFor="let item of (list$ | async);">
item
</li>
</ul>
`,
changeDetection: ChangeDetectionStrategy.OnPush
)
export class ListComponent
public list$: Observable<any[]>;
constructor(
private _ls: ListService
)
ngOnInit()
this.list$ = this._ls.list$;
this._ls.loadList();
如果 loadList 内容通过 http 调用获取列表内容,则视图会更新,如果列表内容是静态的,则视图不会更新。
如果我将列表更新包装在 setTimeout 中,它会触发视图更新
setTimeout(() =>
this._list$.next(this.list);
, 1);
我刚开始探索 Observables,谁能指导一下上面的代码有什么问题?
【问题讨论】:
【参考方案1】:只需将代码从ngOnInit()
移至构造函数即可。 Angular 在调用 ngOnInit()
之前尝试解析绑定(订阅 observable)并失败,因为 thod._list$
是 null
并且稍后不会尝试,因为它无法识别更改。
【讨论】:
非常感谢 Günter 的回复。但这似乎并不能解决问题。如果服务中的 loadList 方法进行 http 调用,或者将其包装在 setTimeout(() => this._list$.next(this.list); , 1);它有效,否则无效。setTimeout()
导致更改检测运行。您是否真的尝试将代码移动到构造函数?您可以尝试将第一行移至构造函数。
是的,我移动了这一行 this.list$ = this._ls.list$;到构造函数。
我也尝试添加 this.list$.subscribe((data) => console.log(data); );到 ngOnInit() 以确认数据是否实际上是从服务发送的,并且日志显示该数据实际上正在被检索但视图没有更新。
你使用的是哪个 Angular2 版本?以上是关于带有 ChangeDetectionStrategy.OnPush 和异步管道的 Angular 2 Observable 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 uuencode 的“sendmail”发送邮件,并带有主题
如何翻转正面带有标签而背面带有另一个标签的视图 - 参见图片
CakePHP 如何处理带有/不带有 'id' 字段的 HABTM 表?
带有 RecyclerView 的 DialogFragment 比带有 Recyclerview 的 Fragment 慢