问题描述
我看了几个与ChangeDetectionStrategy
相关的主题,我对它的不同用法感到困惑。我只是想在父组件上更改数据时更新子组件中的数据。为此,我看到changeDetection: ChangeDetectionStrategy.OnPush
已添加到父级的Component
字段中,但是我不确定是否应该使用ChangeDetectorRef
参数或某些默认方法,例如ngDoCheck()
方法。那么,如何在父子组件之间执行此操作?我应该显式添加来自父级的参数,还是会自动更新@Input
变量?
import { Component,Input,ChangeDetectionStrategy,ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'app-child',templateUrl: './child.component.html',changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent {
@input() data: string[];
constructor(private cd: ChangeDetectorRef) {}
refresh() {
this.cd.detectChanges();
}
}
解决方法
ChangeDetectionStrategy.OnPush
的不同之处在于,只有在发生以下类似情况时,您的组件才会检测到更改:
- 输入参考更改
- 一个事件源自该组件或其子组件
- 在视图中使用异步管道
- 明确运行更改检测
因此,如果您不更改输入的引用,则必须手动检测更改。
这是stackblitz,显示了OnPush
和Default
使用 ChangeDetectionStrategy.OnPush ,您的子组件仅在 @Input 中的数据确实更新时才执行更新,因此您需要数据不可变,那些在更新了Angular数据后将执行ChangeDetector并更新组件视图。
您可以检查以下示例:https://angular-cd-immutable-example.stackblitz.io
,一种方法是使用slice方法创建对数组的新引用。
A full stackblitz example can be seen here.
app.component.html
<button
(click)="people.push({firstName: '1',lastName: '1'}); people = people.slice()">
+</button>
<div>
<p> {{ people | json }} </p>
</div>
<br/>
<person [persons]="people"></person>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-app',templateUrl: './app.component.html',styleUrls: [ './app.component.css' ]
})
export class AppComponent {
people: any[] = [
{
firstName: "Alex1",lastName: "Brown1",age: 55,},{
firstName: "Foo2",lastName: "Bar2",age: 44,{
firstName: "Fido3",lastName: "Johnson3",age: 14,}
]
}
和person.component.html
<div *ngFor="let person of persons">
Hello I am {{person.firstName}} and I am {{ person.age}}
</div>
和person.component.ts
import { Component,OnInit,Input,ChangeDetectionStrategy,ChangeDetectorRef } from '@angular/core';
class test {}
@Component({
selector: 'person',templateUrl: './person.component.html',styleUrls: ['./person.component.css'],changeDetection: ChangeDetectionStrategy.OnPush
})
export class PersonComponent implements OnInit {
@Input() persons: any;
}