我有这个指令:
angular.module("app", [])
.directive("myDirective", myDirective);
function myDirective() {
return {
template: '{{vm.numbers}}',
scope: {
numbers: '='
},
controller: MyController,
controllerAs: 'vm',
bindToController: true,
};
}
function MyController($timeout) {
var vm = this;
vm.numbers.push(3);
$timeout(function() {
vm.numbers.push(4);
});
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app">
<my-directive numbers="[1,2]"></my-directive>
</div>
为什么3没有被推到阵列?
答案 0 :(得分:3)
=
和@
之间存在明显的语法差异。双向=
绑定的一个特性是,当属性值不是作用域属性名称时,应该小心处理,因为它不适用于此。
在您的示例中发生的事情是'[1,2]'字符串被解析为数组,并且在控制器函数运行时可用作vm.number
范围属性。使用vm.numbers.push(3)
所做的更改已应用于匿名数组的副本,并且未在任何位置观察到这些更改。控制器功能完成后,第一个摘要周期启动,vm.number
再次被[1, 2]
数组覆盖。之后$timeout
函数启动并使用vm.numbers.push(4)
进行另一项更改。 vm.number
的变化仅在此时才被观察到。
当匿名数组或对象被馈送到双向指令绑定时会发生这种情况。将vm.number
分配给其他人也会遇到问题。
由于@
绑定仅适用于文本,因此它也不是一个选项。你可以这样做
function myDirective() {
return {
template: '{{vm.numbers}}',
scope: {},
controller: MyController,
controllerAs: 'vm',
bindToController: true,
};
}
function MyController($timeout, $parse, $attrs) {
var vm = this;
vm.numbers = $parse($attrs.numbers)() || [];
vm.numbers.push(3);
$timeout(function() {
vm.numbers.push(4);
});
}
答案 1 :(得分:1)
当控制器执行时,vm.numbers
会根据您的逻辑进行更新。然后链接阶段启动并且范围变量从您的标记和范围中的名称设置,但您将失去控制器的临时更改。
我添加了一些显示此序列的控制台日志:
in controller=> [1, 2, 3]
in link, scope=> [1, 2, 3] attrs=> [1,2]
in timeout method=> [1, 2]
一种方法是@estus建议的,自己连接参数。另一种方法可能是重写逻辑,以便您可以依靠angular来管理传递的。