我有一个AngularJS组件,该组件通过单向双向(=
)数据绑定来接受数组。在父级中,我有一个按钮,其ng-click映射到此功能:
onClickAddValue()
{
this.listOfValues.push(this.valueInput);
}
其中this.listOfValues
是通过绑定传递给子组件的。此代码无效(子组件的视图未更新)。作为一个聪明的cookie,他事先完成了有关AngularJS的作业,我知道这是因为listOfValues
的值没有改变,它仍然是相同的对象引用。所以我这样做:
onClickAddValue()
{
var oldList = this.listOfValues;
this.listOfValues = [];
for (let value of oldList)
{
this.listOfValues.push(value);
}
this.listOfValues.push(this.valueInput);
}
但这也不起作用!我还尝试了Object.assign
和angular.copy
。好像我的子组件根本没有注意到其输入的任何更改。但显然可以,因为下面的代码确实有效!
onClickAddValue()
{
var oldList = this.listOfValues;
this.listOfValues = null;
setTimeout(
() =>
{
this.listOfValues = oldList;
this.listOfValues.push(this.valueInput);
this.$scope.$digest();
}
);
}
这是怎么回事?我可以看到为什么最后一个代码段有效-listOfValues
设置为null,ng-click
自动触发摘要,角度通知新的null值,因此它更新视图,然后立即更新{{1 }}再次更改,另一个摘要被手动触发,视图再次更新。但是,为什么其他版本不起作用?为什么更改对象不同于将其更改为null,然后然后对其进行更改?
答案 0 :(得分:1)
我正在监听对
$onChanges
中绑定的$onChanges
的更改
使用Array.concat创建一个新对象, onClickAddValue()
{
this.listOfValues.push(this.valueInput);
this.listOfValues = this.listOfValues.concat();
}
将检测到该对象:
$onChanges
Array.push
Life-Cycle Hook仅检查引用的更改。它不检查内容更改。用Array.concat
更改内容之后。使用angular.module("app",[])
.controller("ctrl", class {
constructor () {
this.listOfValues = [3,5];
}
onClickAddValue()
{
this.listOfValues.push(this.valueInput);
this.listOfValues = this.listOfValues.concat();
}
})
.component("myComponent",{
bindings: {values: "<"},
template: `
<fieldset>
{{$ctrl.values}}<br>
changes={{$ctrl.changes}}
</fieldset>
`,
controller: class {
constructor () {
this.changes=0;
}
$onChanges(ch) {
this.changes++;
//console.log(ch);
}
}
})
方法来创建一个新的对象,该对象将被变更检测器检测到。
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl as $ctrl">
<input ng-model="$ctrl.valueInput" /><br>
<button ng-click="$ctrl.onClickAddValue()">Add value</button>
<br>
{{$ctrl.listOfValues}}
<my-component values="$ctrl.listOfValues"></my-component>
</body>
listOfValues
我做了很多工作,我认为这实际上与
=
是通过<
绑定而不是<
绑定绑定到子组件这一事实有关的-更改为$ngChanges
绑定会使其突然起作用
'@'
的文档清楚地说明了它具有属性('<'
)和单向($onChanges(changesObj)
)绑定的作用。
从文档中:
生命周期挂钩
<
-每当单向(@
)或插值(changesObj
)绑定更新时调用。{ currentValue, previousValue, isFirstChange() }
是一个哈希,其键是已更改的绑定属性的名称,值是"="
形式的对象。使用此挂钩可触发组件内的更新,例如克隆绑定值以防止外部值的意外突变。请注意,初始化绑定时也会调用此方法。— AngularJS Comprehensive Directive API Reference - Life-Cycle Hooks
应避免双向({{1}})绑定,因为它增加了额外的监视程序,并且使向Angular 2+的迁移更加困难。
有关更多信息,请参见AngularJS Developer Guide - Component-based Application Architecture。