Pass parameter to Angularjs controller function fr

2019-09-08 15:29发布

I have a AngularJs directive that creates a property and callback function on its isolated scope:

.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>';
    }
};}])

In the directive a button gets clicked and it executes the onButtonClicked function. This then sets a scope variable and calls the $scope.myCallBack function.

The callBack function gets executed and does the following: console.log($scope.linkedVariable);

The problem is the $scope.linkedVariable has not yet been updated and at that stage the $scope.linkedVariable is still the previous value.

When I wrap the above code in a setTimeout the correct value is retrieved: setTimeout(function(){console.log($scope.linkedVariable)}, 2000);

My Question is, how to properly pass the value to the onCallBack function.

Please see full code example below:

   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条回答
地球回转人心会变
2楼-- · 2019-09-08 15:46

I found a more acceptable/correct way of overcoming my problem thanks to http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters.

Instead of accessing the $scope.linkedVariable in the controller, I now accept the value as a parameter to the function.

To get this to work I had to change the function declaration in the HTML to:

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

The controller function declaration:

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

the directive can then call the function like:

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

Please see a updated JSFiddle: http://jsfiddle.net/ff5ck0da/9/

查看更多
Ridiculous、
3楼-- · 2019-09-08 15:48

You can even change the settimeout to

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

this will push the resolution of the variable to the bottom of the async stack. And thus evaluate after the angular digest loop is done ( in essence the variable value is set)

If you dont want to use settimeout you can use this:

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

here you are essentially telling angular to not use a copy but the actual parent variable.

查看更多
登录 后发表回答