- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我不明白为什么子组件的更改检测会在这种情况下运行:
import { Component, ChangeDetectionStrategy } from '@angular/core'
@Component({
selector: 'app-root',
template: `
<cmp [ticks]="ticks" (update)="onUpdate($event)"></cmp>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
ticks = 0;
onUpdate(event) {
console.log(this.ticks);
}
}
import { Component, ChangeDetectionStrategy, OnInit, Input, Output, EventEmitter, OnChanges } from '@angular/core';
@Component({
selector: 'cmp',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `<p>Number of ticks: {{ticks}}</p>
`
})
export class CmpComponent implements OnInit, OnChanges {
@Input('ticks') ticks: number;
@Output() update: EventEmitter<number> = new EventEmitter();
ngOnInit() {
setInterval(() => {
this.ticks++;
this.update.emit(this.ticks);
}, 1000);
}
ngOnChanges() {
console.log('changed');
}
}
当我运行此“刻度数”时, subview 中会更新。
当我删除监听父级中的事件时,它不会更新 View 。
我的理解如下:
因为父级实现了 OnPush 策略,所以当它监听子级发出的事件时,它会触发更改检测。收到事件后,它不会更改“tick”,因此子组件的 @Input() 不会更新。然而,也实现 OnPush 策略的子组件会更新其 View 。因此,它的行为就好像它的 @Input 发生了变化。
根据我的研究:
使用 OnPush 策略,如果满足以下条件,则会对组件进行更改检测:
这些似乎都不适用于子组件。
有什么解释吗?非常感激。
最佳答案
首先感谢您提出了一个好问题。
使用 Angular 2.x.x 它将按照您期望的方式工作。
https://plnkr.co/edit/TiOeci5Lr49xvRB5ozHb?p=preview
但是在 Angular4 中引入了新的 View 引擎,所有代码都被完全覆盖。
https://plnkr.co/edit/SFruiPXEhMmYDP7WuBbj?p=preview
当事件发生时,Angular 会调用一些名为 markForCheck
的方法。
Angular 2 版本
AppView.prototype.markPathToRootAsCheckOnce = function () {
var /** @type {?} */ c = this;
while (isPresent(c) && c.cdMode !== ChangeDetectorStatus.Detached) {
if (c.cdMode === ChangeDetectorStatus.Checked) {
c.cdMode = ChangeDetectorStatus.CheckOnce;
}
if (c.type === ViewType.COMPONENT) {
c = c.parentView;
}
else {
c = c.viewContainer ? c.viewContainer.parentView : null;
}
}
};
Angular 4 版本
function markParentViewsForCheck(view) {
var /** @type {?} */ currView = view;
while (currView) {
if (currView.def.flags & 2 /* OnPush */) {
currView.state |= 8 /* ChecksEnabled */;
}
currView = currView.viewContainerParent || currView.parent;
}
}
尽管代码看起来完全不同,但这里没有区别。它从当前组件开始,并启用对所有父组件直至根组件的检查。
我突出显示了短语从当前组件开始,因为这正是已更改的内容。
Angular 2.x.x 以 AppComponent
View_App0.prototype.handleEvent_4 = function(eventName,$event) {
var self = this;
self.debug(4,2,3);
self.markPathToRootAsCheckOnce(); // self is AppComponent view
var result = true;
if ((eventName == 'update')) {
var pd_sub_0 = (self.context.onUpdate($event) !== false);
result = (pd_sub_0 && result);
}
return result;
};
Angular 4 以 CmpComponent
开头
function dispatchEvent(view, nodeIndex, eventName, event) {
var nodeDef = view.def.nodes[nodeIndex];
var startView = nodeDef.flags & 33554432 /* ComponentView */ ? asElementData(view, nodeIndex).componentView : view;
markParentViewsForCheck(startView);
return Services.handleEvent(view, nodeIndex, eventName, event);
}
因此CmpComponent
将被打开进行检查
关于Angular ChangeDetectionStrategy.OnPush 与发出事件的子组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44607202/
在过去几年从事 React 项目之后,我才开始接触 Angular。 我有一个使用 changeDetection: ChangeDetectionStrategy.OnPush 的组件,但我不喜欢我
我不明白为什么子组件的更改检测会在这种情况下运行: import { Component, ChangeDetectionStrategy } from '@angular/core' @Compon
我不明白为什么子组件的更改检测会在这种情况下运行: import { Component, ChangeDetectionStrategy } from '@angular/core' @Compon
我正在尝试熟悉 Angular 2 的 ChangeDetectionStrategy.OnPush 性能提升(如 here 所述)。但我这里有古玩盒。 我有父 AppComponent: @Comp
我正在构建一个包含许多组件的 Angular 4 应用程序,其中 ChangeDetectionStrategy 是 OnPush。同时the Angular Documentation on the
我是否应该始终在我的组件中使用 ChangeDetectionStrategy.OnPush? 我总是听说 OnPush 非常棒,它解决了很多问题,加快了 Angular 应用程序的速度,甚至摆脱了
我有一个使用服务提交一些数据的组件。 该组件使用 ChangeDetectionStrategy.OnPush ,但发生了一些奇怪的事情: 当请求 成功 : next回调被调用,formStatus更
正如标题所说:我正在处理一个非常大的项目,而且我使用过的组件很少 ChangeDetectionStrategy.OnPush以免表现不佳。我想知道,将策略的每个组件都放入“好”,以防万一,使用 Ch
https://stackblitz.com/edit/angular-xpamld 问题:有人能帮我理解为什么我的原型(prototype)的 changeDetection: ChangeDete
如何将 ChangeDetectionStrategy.OnPush 设置为每个的默认策略我的应用程序中的组件,而不是在每个组件的模板上编写changeDetection: ChangeDetecti
我试图了解 ChangeDetectionStrategy.OnPush机制。 我从我的读数中收集到的是,通过将旧值与新值进行比较来进行更改检测。如果对象引用未更改,则该比较将返回 false。 但是
我有这个简单的组件。 @Component({ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'app-spinner'
在我的 Angular 应用程序中,我通过实现 ControlValueAccessor 创建了一个自定义表单元素。界面。 因此,在我的组件中,我正确实现了该接口(interface)的所有方法,包括
我有 Angular 分量 l @Component({ selector: 'aas-add-option', templateUrl: './add-option-modal.compon
假设我有一个这样的组件结构: AppComponent HeaderComponent ContentComponent TodosComponent
我正在使用可观察对象将服务列表返回到我的组件,在我的组件中我使用 ChangeDetectionStrategy.OnPush,在模板中我使用异步管道,希望这会带来一些性能优势,因为未执行更改检测所有
我转载了一个简单的stackblitz证明我一直遇到的问题。问题是我有一个将 bool 值传递给子组件的父组件。这个 bool 值是子组件上的@Input。需要注意的是,父组件使用 ChangeDet
我有一个容器组件,其中注入(inject)了一个服务。该服务包含一个可观察的。在容器组件的模板中,我使用异步管道将该可观察对象绑定(bind)到子组件的输入属性。一切似乎都正常,除了我必须与 UI 交
我有两个组件,我在其中使用 ChangeDetectionStrategy.OnPush。父组件: @Component({ changeStaregy: ChangeDetecti
我正在使用 OnPush 策略并根据此 article如果没有输入更改,则无需检查组件的模板。但在我的示例中,当我单击触发按钮并且输入没有更改时,在这种情况下 ngAfterViewChecked H
我是一名优秀的程序员,十分优秀!