控制器通信指令

时间:2017-01-09 07:43:16

标签: javascript angularjs

我有一个用例,我想创建一个指令,它执行一些处理并将一个数组返回给控制器。

我的指令看起来像

    angular.module('directives').directive('reuse','testService',function(testService) {
      return { 
         restrict : 'E', 
         replace : true, 
         scope : 
                { elements: '=elements',  
                  callmethod: '&'
                },
         controller: testController,
         templateUrl: '/abc.html'
        };
   }]);

testController有一个方法可以监听事件onControllerClick  并调用引用callmethod方法。

    $scope.$on('onControllerClick',function() {
       $scope.elements= ['a','b','c'];
       var x = $scope.elements; // reason for this is explained below
       $scope.callmethod(x);
    }

我创建了一个局部变量x,因为我没有直接得到元素的值,即使数组是双向绑定的。

我从html调用指令就像

   <div>   
      <reuse elements="elements" callmethod="callmethod(elements)" />
      <button type="button" ng-click="broadcastMethod()" />
   </div>

这个html的控制器看起来像

    $scope.elements = [];
    $scope.broadcastMethod = function() {
        $scope.$broadcast('onControllerClick');
    };
    $scope.callmethod = function(parameterElement) {
      console.log(parameterElement);
      console.log($scope.elements);
    }

我遇到这种方法的问题是,每当我第一次点击按钮时,parameterElement$scope.elements的值都将变为空数组。但是当我第二次点击按钮时,两个值都按预期工作。我第一次失踪的是什么?

P.S:我知道明显的建议答案是使用服务,但我正在寻找一种不使用它们的解决方案。

1 个答案:

答案 0 :(得分:0)

使用表达式&绑定时,解析后的表达式求值函数接受局部变量上下文对象:

$scope.$on('onControllerClick',function() {
   $scope.elements= ['a','b','c'];
   var x = $scope.elements; // reason for this is explained below
   //$scope.callmethod(x);
   var locals = {$elements: x};
   $scope.callmethod(locals);
}

然后在HTML中:

<div>   
  <reuse elements="elements" callmethod="parentMethod($elements)"></reuse>
  <button type="button" ng-click="broadcastMethod()" />
</div>

当指令调用$scope.callmethod(locals)函数时,callmethod属性定义的Angular Expression将使用父作用域进行评估。在本地上下文对象中定义的任何变量都将覆盖父作用域变量。

推荐:使用美元符号$作为前缀的局部变量,以区别于父作用域变量。

  

我没有直接得到元素的值,即使数组是双向绑定的。

在使用隔离范围的指令中使用表达式&绑定和双向=绑定时,这是一个常见问题。由于双向=绑定使用观察程序将值从指令范围传输到父范围,因此可能存在滞后。表达式&绑定的表达式在双向绑定执行传输之前执行。

推荐:避免双向=绑定。而是使用单向<绑定和表达式&绑定本地上下文变量。这将使更容易过渡到Angular 2+并避免其他问题。

进一步阅读:AngularJs 1.5 - Component does not support Watchers, what is the work around?