从指令

时间:2015-07-02 10:07:42

标签: angularjs angularjs-directive angularjs-scope

我有一个AngularJs指令,它在其隔离的范围内创建一个属性和回调函数:

.directive('testButton', [function () {
  return {
    restrict: 'A',
    controller: 'TestDirectiveController as vmDirective',
    scope: {     
        myCallBack:'&myCallBack',
        myVariable: '=myVariable'
    },
    template: function (element, attrs) {
        return '<button data-ng-click="vmDirective.onButtonClicked(2)">Set myVariable = 2</button>';
    }
};}])

在指令中单击一个按钮并执行onButtonClicked功能。然后设置范围变量并调用$scope.myCallBack函数。

执行callBack函数并执行以下操作: console.log($scope.linkedVariable);

问题是$scope.linkedVariable尚未更新,在此阶段$scope.linkedVariable仍然是之前的值。

当我在setTimeout中包含上述代码时,会检索到正确的值:setTimeout(function(){console.log($scope.linkedVariable)}, 2000);

我的问题是,如何将值正确传递给onCallBack函数。

请参阅下面的完整代码示例:

   angular.module('application',[])

   .directive('testButton', [function () {
      return {
         restrict: 'A',
         controller: 'TestDirectiveController as vmDirective',
         scope: {     
              myCallBack:'&myCallBack',
              myVariable: '=myVariable'
         },
         template: function (element, attrs) {
            return '<button data-ng-click="vmDirective.onButtonClicked(2)">Set myVariable = 2</button>';
         }
       };
    }])

  .controller("TestDirectiveController", ['$scope', function($scope){
       var self = this;
       self.onButtonClicked = function(value){
          $scope.myVariable = value;
          $scope.myCallBack();
       };
   }])

  .controller("TestController", ['$scope', function($scope){
      var self = this;
      $scope.linkedVariable = null;

      self.onCallBack = function(){
      console.log($scope.linkedVariable);
      setTimeout(function(){console.log($scope.linkedVariable)}, 2000);
    };
 }])

HTML:

<div data-ng-controller="TestController as vm">
   <div data-test-button="" data-my-call-back="vm.onCallBack()" data-my-variable="linkedVariable"></div>
</div>

jsfiddle:http://jsfiddle.net/ff5ck0da/1/

2 个答案:

答案 0 :(得分:2)

由于http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters,我找到了一种更可接受/更正确的方法来克服我的问题。

我现在接受该值作为函数的参数,而不是访问控制器中的$scope.linkedVariable

为了使其工作,我不得不将HTML中的函数声明更改为:

data-my-call-back="vm.onCallBack"

控制器功能声明:

self.onCallBack = function(myVariable){
    console.log(myVariable);        
};

然后该指令可以调用函数:

self.onButtonClicked = function(value){        
    $scope.myCallBack()(value);
};

请参阅更新后的JSFiddle:http://jsfiddle.net/ff5ck0da/9/

答案 1 :(得分:0)

您甚至可以将settimeout更改为

setTimeout(function(){console.log($scope.linkedVariable)}, 0);

这会将变量的分辨率推到异步堆栈的底部。 因此在角度摘要循环完成后进行评估(实质上是设置变量值)

如果您不想使用settimeout,可以使用:

self.onCallBack = function(){
        var accessor = $parse($scope.linkedVariable);
        $scope.value = angular.copy(accessor($scope.$parent));
        console.log($scope.linkedVariable);
};

这里你基本上是告诉角度不使用副本而是使用实际的父变量。