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.
source to share
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 .
source to share