Javascript 更改控制器初始化中的作用域不适用于指令

Javascript 更改控制器初始化中的作用域不适用于指令,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我有这个指示: 角度模块(“应用程序”,[]) .指令(“我的指令”,我的指令); 函数MyDirection(){ 返回{ 模板:“{vm.numbers}}”, 范围:{ 编号:'=' }, 控制器:MyController, controllerAs:'vm', bindToController:对, }; } 函数MyController($timeout){ var vm=这个; 虚拟机号码推送(3); $timeout(函数(){ 虚拟机数推送(4); }); } 在=和@之间有

我有这个指示:

角度模块(“应用程序”,[]) .指令(“我的指令”,我的指令); 函数MyDirection(){ 返回{ 模板:“{vm.numbers}}”, 范围:{ 编号:'=' }, 控制器:MyController, controllerAs:'vm', bindToController:对, }; } 函数MyController($timeout){ var vm=这个; 虚拟机号码推送(3); $timeout(函数(){ 虚拟机数推送(4); }); }


=
@
之间有明显的语法差异。双向
=
绑定的一个特性是,当属性值不是作用域属性名时,您应该小心处理,因为它不是用于此目的的

在您的示例中发生的情况是,“[1,2]”字符串被解析为数组,并且在控制器函数运行时作为
vm.number
scope属性可用。使用
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);
  });
}

当控制器执行时,
vm.numbers
会根据您的逻辑进行更新。然后链接阶段开始,范围变量从标记和范围中的名称中设置,但您丢失了控制器中的临时更改

我添加了一些控制台日志,其中显示了以下顺序:

in controller=> [1, 2, 3]
in link, scope=> [1, 2, 3] attrs=> [1,2]
in timeout method=> [1, 2]

一种方法是@estus建议,自己连接参数。另一种方法可能是重写逻辑,以便依靠angular来管理传递的数据。

您已经创建了一个名为“myController”的函数,但您没有将其作为控制器应用于模块,也没有将其应用于视图中的任何对象以实例化它。@davidpini它是一个指令控制器