3 回答
TA贡献1712条经验 获得超3个赞
两者之间的最大区别是detectChanges()实际上触发变更检测,而markForCheck()不会触发变更检测。
detectChanges
该代码用于从触发您的组件开始对组件树进行更改检测detectChanges()。因此,更改检测将针对当前组件及其所有子组件运行。Angular在中保留对根组件树的引用ApplicationRef,当发生任何异步操作时,它会通过包装方法触发对该根组件的更改检测tick():
@Injectable()
export class ApplicationRef_ extends ApplicationRef {
...
tick(): void {
if (this._runningTick) {
throw new Error('ApplicationRef.tick is called recursively');
}
const scope = ApplicationRef_._tickScope();
try {
this._runningTick = true;
this._views.forEach((view) => view.detectChanges()); <------------------
view这是根组件视图。正如我在引导多个组件的含义中所描述的那样,可能有许多根组件。
@milad描述了您可能需要手动触发更改检测的原因。
markForCheck
就像我说的,这个家伙根本不会触发变更检测。它只是从当前组件向上扩展到根组件,并将其视图状态更新为ChecksEnabled。这是源代码:
export function markParentViewsForCheck(view: ViewData) {
let currView: ViewData|null = view;
while (currView) {
if (currView.def.flags & ViewFlags.OnPush) {
currView.state |= ViewState.ChecksEnabled; <-----------------
}
currView = currView.viewContainerParent || currView.parent;
}
}
组件的实际更改检测未计划,但将来会发生时(作为当前或下一个CD周期的一部分),即使父组件视图已脱离更改检测器,也将对其进行检查。可以通过使用cd.detach()或指定OnPush更改检测策略来分离更改检测器。所有本机事件处理程序都将所有父组件视图标记为要检查。
这种方法通常在ngDoCheck生命周期挂钩中使用。如果您认为这ngDoCheck意味着正在检查您的组件。
TA贡献1890条经验 获得超9个赞
商店更新主要是由于获取或设置isFetching before导致的。并在获取后..但是我们不能总是使用,async pipe
因为在订阅内部,我们通常有一些事情要做call setFromValues
do some comparison
..如果async
本身调用markForCheck
它,那么如果我们自己调用它会带来什么问题呢?但是同样,在ngOnInit
获取不同数据时,我们通常会有2-3个或更多选择器……而我们markForCheck
都将它们都调用了。
- 3 回答
- 0 关注
- 2827 浏览
添加回答
举报