Angular:模型用 ChangeDetectionStrategy.OnPush 收听
Angular: Model listening with ChangeDetectionStrategy.OnPush
假设我有一个大的 Json 模型,我的后端发送到我的前端,看起来像这样:
{
dataA: { //some object },
dataB: { //some object },
dataC: { //some object },
...
}
现在假设我有将 dataA 作为 @Input()
的 ComponentA,将 dataB 作为 @Input()
的 ComponentB,等等:
@Component({
selector: 'comp-a'
})
class ComponentA {
@Input() _dataA;
}
@Component({
selector: 'comp-b'
})
class ComponentA {
@Input() _dataB;
}
// .... other components
@Component({
selector: 'app',
template:`
<comp-a [_dataA]="dataA"></comp-a>
<comp-b [_dataB]="dataB"></comp-b>
...
`
})
class AppComponent {
}
我想让这些组件使用 OnPush 变化检测策略。
收到新模型时,可能会发生模型中的数据字段与先前模型中的先前值没有变化的情况,因此我不希望将它们再次传递为 @Input()
到组件以避免运行无意义的更改检测。
在将其数据作为 @Input()
传递给我的组件之前,是否有某种聪明的方法可以在前端检测我的模型的变化,并仅在它们各自的数据发生变化时通知它们?或者我应该让 Angular 自己执行变化检测吗? OnPush 在这里真的合适吗?
OnPush 通过不检查模型属性来提高效率,并在对象的实例发生更改时触发更新,而不是对象的属性。要执行您的建议,将涉及检查对象的属性以查看是否有任何更改。你基本上会重新发明变化检测,所以我不明白这一点,你需要做得比 Angular 团队做得更好才能看到任何好处。
你也用rxjs标记了这个问题,但问题中没有关于rxjs的内容。实现 OnPush 变化检测的最佳方式是使用 rxjs observables 并在模板中使用异步管道。通过这种方式,您只能让可观察对象发出更新后的值。
@Component({
selector: 'app',
template:`
<comp-a [_dataA]="dataA$ | async"></comp-a>
<comp-b [_dataB]="dataB$ | async"></comp-b>
...
`
})
class AppComponent {
dataA$ = new BehaviorSubject<DataAModel>(undefined);
dataB$ = new BehaviorSubject<DataBModel>(undefined);
updateA() {
if (a has changed) { // If your detection to check changes is inefficient then there is no point
this.dataA$.next(a);
}
}
updateB() {
if (b has changed) {
this.dataB$.next(b);
}
}
}
假设我有一个大的 Json 模型,我的后端发送到我的前端,看起来像这样:
{
dataA: { //some object },
dataB: { //some object },
dataC: { //some object },
...
}
现在假设我有将 dataA 作为 @Input()
的 ComponentA,将 dataB 作为 @Input()
的 ComponentB,等等:
@Component({
selector: 'comp-a'
})
class ComponentA {
@Input() _dataA;
}
@Component({
selector: 'comp-b'
})
class ComponentA {
@Input() _dataB;
}
// .... other components
@Component({
selector: 'app',
template:`
<comp-a [_dataA]="dataA"></comp-a>
<comp-b [_dataB]="dataB"></comp-b>
...
`
})
class AppComponent {
}
我想让这些组件使用 OnPush 变化检测策略。
收到新模型时,可能会发生模型中的数据字段与先前模型中的先前值没有变化的情况,因此我不希望将它们再次传递为 @Input()
到组件以避免运行无意义的更改检测。
在将其数据作为 @Input()
传递给我的组件之前,是否有某种聪明的方法可以在前端检测我的模型的变化,并仅在它们各自的数据发生变化时通知它们?或者我应该让 Angular 自己执行变化检测吗? OnPush 在这里真的合适吗?
OnPush 通过不检查模型属性来提高效率,并在对象的实例发生更改时触发更新,而不是对象的属性。要执行您的建议,将涉及检查对象的属性以查看是否有任何更改。你基本上会重新发明变化检测,所以我不明白这一点,你需要做得比 Angular 团队做得更好才能看到任何好处。
你也用rxjs标记了这个问题,但问题中没有关于rxjs的内容。实现 OnPush 变化检测的最佳方式是使用 rxjs observables 并在模板中使用异步管道。通过这种方式,您只能让可观察对象发出更新后的值。
@Component({
selector: 'app',
template:`
<comp-a [_dataA]="dataA$ | async"></comp-a>
<comp-b [_dataB]="dataB$ | async"></comp-b>
...
`
})
class AppComponent {
dataA$ = new BehaviorSubject<DataAModel>(undefined);
dataB$ = new BehaviorSubject<DataBModel>(undefined);
updateA() {
if (a has changed) { // If your detection to check changes is inefficient then there is no point
this.dataA$.next(a);
}
}
updateB() {
if (b has changed) {
this.dataB$.next(b);
}
}
}