你可以在这里看到我的Plunk . 在这个非常简单的例子中,我传递了一个函数
_ => {
console.log(number);
}
到具有@Input属性的子组件 . 我的父组件看起来像这样:
@Component({
selector: 'my-app',
template: `
<child [func]="getFunction(3)">
</child>
<button type="button" (click)="startChangeDetection()">
Start change detection
</button>
`,
directives : [Child],
styles:[`
.titles {
color:#0099FF
}
.child-style {
background-color:#00ffff
}
` ],
})
export class CarComponent {
startChangeDetection()
{
}
getFunction(number)
{
return _ => {
console.log(number);
}
}
}
该按钮不会触发另一轮更改检测(回调函数中没有实现 . 但是,我的更改检测始终将我的输入识别为更改,但是它更改了 . 这是我的子组件:
@Component({
selector: 'child',
template: `
<h2>Child Component</h2>
`,
inputs: ['func']
})
export class Child {
private func;
ngOnChanges(changes)
{
console.log(changes.func.previousValue.toString());
console.log(changes.func.currentValue.toString());
}
}
你可以看到,在ngOnChanges中我将我的功能记录到控制台 . 但是记录的值(显然)永远不会改变,所以输出始终是:
function (_) {
console.log(number);
}
function (_) {
console.log(number);
}
为什么Angular甚至会调用ngOnChanges?为什么它认为有任何变化?
2 回答
每次调用
getFunction
时,此方法都会返回不同的函数实例 .因为
<child [func]="getFunction(3)">
,每次运行更改检测时都会调用getFunction
.绑定到函数通常不是最好的主意 . 如果以这种方式移出函数创建,则每次都返回相同的函数实例,并且角度变化检测不会将其识别为更改:
我没有看到任何异常 . 变更检测被调用两次 .
第一次因为子组件在汽车组件内呈现 . 组件树已更改 .
第二次,因为函数getFunction在将它作为
getFunction(3)
传递给输入时被调用 . 这相当于输入值的变化,从而触发变化检测周期 .