Roy*_*mir 3 javascript angular
关于ChangeDetectorRef,我已经知道——
detectChanges实际触发更改检测,同时 -markForCheck- 组件的实际更改检测未 安排,但在将来何时发生(作为当前或下一个 CD 周期的一部分)
看着markForCheck- 如果它没有被安排,那么它什么时候运行?显然在 Observables 回调、异步回调和 setTimout 和事件之后。
该文档有一个带有OnPush策略的组件
@Component({
selector: 'cmp',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `Number of ticks: {{numberOfTicks}}`
})
class Cmp {
numberOfTicks = 0;
constructor(private ref: ChangeDetectorRef) {
setInterval(() => {
this.numberOfTicks++;
// the following is required, otherwise the view will not be updated
this.ref.markForCheck();
}, 1000);
}
}
Run Code Online (Sandbox Code Playgroud)
题:
如果它标记为检查其祖先,则为下一个周期,那么谁运行当前周期?(它是上一个 setTimeout 调用吗?)
因为这段代码显示每一秒都被另一个替换——换句话说,每一秒都有一个变化检测(?!)。
通过 POV 的步骤实际上发生了什么?
markForCheck, as you guessed, and as the name suggests, will tell the Angular to mark the component to be change-detectable for the next cycle.
When you're writing setInterval, this is what you're actually writing:
constructor(private ref: ChangeDetectorRef) {
setInterval(() => {
this.numberOfTicks++;
// the following is required, otherwise the view will not be updated
this.ref.markForCheck();
detectChangesFromZoneJS(); // this is a psudo code, but you can imagine something like this will happen, which is patched by NGZone
// Note that this is the last function that will always be called by Zone at the end of all the async events
}, 1000);
}
Run Code Online (Sandbox Code Playgroud)
This is handled by ZoneJS.
Zone monkey patches all of the async events, and when they finish, Zone will notify Angular and then Angular. knows it's time to detect the changes ( update the view based on the latest model changes), but when you're component is OnPush is not going to detect the changes, unless there has special things happened inside the component, ( like a click event, or any of the @input's is changed).
So when you're deliberately saying markForCheck, you're basically saying: "I know you shouldn't detect the changes because it's OnPush only, but I'm telling you to detect it anyway"
So here is step by step:
Component is initialized, Angular will detect all the changes, your view is updated
You run a setInterval, inside it, you're mutating your model, Angular knows it shouldn't update the view because it's OnPush
the first interval's callback gets called, we're inside the first function, you're marking the component to be deliberately checked, we're at the end of the interval function ( still the first one interval).
Zone notify's Anguar that an Async event is just finished, time to detect the changes
Angular looks at the OnPush and wants to ignore it, but remembers that you've marked the component to be checked by force
the view get's updated
we go to the second interval and so on.
| 归档时间: |
|
| 查看次数: |
910 次 |
| 最近记录: |