Directive for directive communication in AngularJS

So, I have this filter directive:

app.directive('filter', function(){
  return {
    restrict: 'E',
    transclude: true,
    scope: {
        callFunc: '&'
    },
    template:
            '   <div>' +
            '       <div ng-transclude></div>' +
            '   </div>',
    controller: function($scope, $element, $attrs){
        this.getData = function() {
            $scope.callFunc()
        }
    }
  }   
});

app.directive('positions', function(){
  return {
    require: '^filter', 
    scope: {
        selectedPos: '='
    },
    template:
            '  Positions: {{selectedPos}}' +
            '  <ul>' +
            '   <li ng-repeat="pos in positions">' +
            '           <a href="#" ng-click="setPosition(pos); posRegData()">{{pos.name}}</a></a>' +
            '       </li>' +
            '  </ul>',
    controller: function($scope, $element, $attrs){
          $scope.positions = [
            {name: '1'},
            {name: '2'},
            {name: '3'},
            {name: '4'},
            {name: '5'}
          ];
          $scope.selectedPos = $scope.positions[0].name;
          $scope.setPosition = function(pos){
            $scope.selectedPos = pos.name;
          };

    },
    link: function(scope, element, attrs, filterCtrl) {
        scope.posRegData = function() {
            filterCtrl.getData();
        }
    }
  }   
})

      

And the controller:

app.controller('keyCtrl', ['$scope', function($scope) {
  var key = this;
  key.callFunc = function() {
    key.value = key.selectedPos;
    console.log(key.selectedPos)
  }
}]);

      

The main question is: why does key.selectedPos

the controller get the correct value only on the second click?

Here is a plunker copying my problem.


One way to do this is to send a parameter when called callFunc()

Then I update the func in ctrl: key.callFunc = function(filterParams)

but also, I update the passed methodcall-func="key.callFunc(filterParams)

Then in filter directive

I change the getData method to:

this.getData = function(val) {
  $scope.callFunc({filterParams: val})
}

      

In positions directive

passing the value that I need:

scope.posRegData = function() {
  filterCtrl.getData({position: scope.selectedPos});
}

      

Finally, in keyCtrl

I get the following value:

key.callFunc = function(filterParams) {
  key.value = filterParams.position;
  console.log(filterPrams.position)
}

      

Here is a plunker demonstrating this attempt.

The question in this case is if this is a good way to do this, keeping this in mind in a very large application.

+3


source to share


1 answer


This is because isolated areas are at work. The parent area (controller in your case) will be updated after running the digest loop, which ng-click

is called after your function callFunc

. This way you can put your callFunc

code in $timeout

and it will work (but will trigger another digest loop).

Another solution would be to put the value into an object, so when the object changes, the controller (having a reference) will immediately see the update:

In the controller:

key.selectedPos = { value: {}};

key.callFunc = function() {
    key.value = key.selectedPos.value;  
    console.log(key.selectedPos.value)
} 

      



In the directive:

$scope.selectedPos.value = $scope.positions[0].name;
$scope.setPosition = function(pos){
    $scope.selectedPos.value = pos.name;
};

      

See plunker .

+3


source







All Articles