- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试熟悉 Angular 2 的 ChangeDetectionStrategy.OnPush
性能提升(如 here 所述)。但我这里有古玩盒。
我有父 AppComponent
:
@Component({
selector: 'my-app',
template: `<h1>
<app-literals [title]="title" [dTitle]="dTitle"></app-literals>
<input [value]="title.name"/>
</h1>
`
})
export class AppComponent implements OnInit {
title = { name: 'original' };
dTitle = { name: "original" };
constructor(private changeDetectorRef : ChangeDetectorRef) {
}
ngOnInit(): void {
setTimeout(() => {
alert("About to change");
this.title.name = "changed";
this.dTitle = { name: "changed" };
}, 1000);
}
}
和子 LiteralsComponent
组件:
@Component({
selector: 'app-literals',
template: ` {{title.name}}
{{dTitle.name}}`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class LiteralsComponent implements OnInit {
@Input('title') title;
@Input('dTitle') dTitle;
constructor() { }
ngOnInit() {
}
}
我认为将策略设置为 OnPush
会使 Angular 仅反射(reflect)引用的更改,但在示例中我尝试更改(变异)对象的属性, Angular 仍然反射(reflect)它。
this.title.name = "changed";
不应被检测到(因此 UI 不应不反射(reflect)更改)。
这是关于 plunker 的案例
怎么来的?怎样做才是对的?
最佳答案
如果我没理解错,你问的是为什么绑定(bind)值在 LiteralsComponent
模板中更新,即使你不修改引用 title
,而是改变对象.
简短的回答是因为您修改了两者:
this.title.name = "changed";
this.dTitle = {name: "changed"};
在 AppComponent.ngOnInit
中。如果您只修改 this.title.name = "changed"
,您将看到该模板没有更新。
然而,这是一个非常有趣的问题,需要详细探讨
让我们首先从没有 this.dTitle
的 this.title
开始。
首先要了解的是,当您在模板中指定以下内容时:
{{title.name}}
这是 Angular 所做的。它尝试在当前组件实例上找到 title
对象,然后从中获取 name
属性并将其反射(reflect)在 DOM 中。但具有以下配置:
class AppComponent {
title = { name: 'original' }
ngOnInit(): void {
setTimeout(() => {
alert("About to change");
this.title.name = "changed";
}, 1000);
}
}
class LiteralsComponent {
@Input() title;
}
title
对象在两个组件中相同(指向相同的内存位置)。
因此,当 Angular 为 LiteralsComponent
组件运行更改检测时,它会访问您在此处在 AppComponent
中更改的同一对象:
ngOnInit(): void {
setTimeout(() => {
alert("About to change");
this.title.name = "changed";
}, 1000);
}
这里有趣的观察是变化未被检测到,无论是使用 OnPush
还是没有它:
class LiteralsComponent {
@Input() title;
ngOnChanges(changes) {
// will be triggered only for the first CD cycle,
// and won't be triggered when `title` is updated
}
}
现在,最后一件事是了解 DOM 何时更新。根据this article , 它在当前组件的 CD 期间更新。这意味着如果未选中当前组件,则不会更新 DOM。所以我们为 LiteralsComponent
指定 onPush
:
changeDetection: ChangeDetectionStrategy.OnPush,
View 不会更新。
但是,它已在您的问题中更新。为什么?
这就是 dTitle
发挥作用的地方。使用此属性,您实际上是在修改引用,Angular 检测绑定(bind)更改 并为 LiteralsComponent
组件运行 CD。我们在上面了解到,当 CD 运行时,DOM 会更新。所以 Angular 也会更新 {{title.name}}
,因为它指向 AppComponent
中的同一个对象,虽然它没有检测到它被改变了.
关于angular - ChangeDetectionStrategy.OnPush 不符合我的预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43539254/
在过去几年从事 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
我是一名优秀的程序员,十分优秀!