AyoubOlk AyoubOlk - 2 months ago 12
AngularJS Question

bind directive action to parent controller AngularJS

I have a directive for profile update and I want to trigger update action from the parent scope.
Here what look like my code:


main.js


angular.module('app')
.directive('profile',{
scope: {
updateFromDirective: "="
},
template: '<form><input ng-model="name"/></form>',
controller: function(){
this.updateFromDirective = function(){
/* update here */
};
}
})
.controller('Ctrl', function(){
this.updateFromController = function(){
if(condition){
/* how do I call updateFromDirective here ??? */
}
};
});



index.html


<div ng-controller="Ctrl">
<profile updateFromDirective="updateFromController"></profile>
<button ng-click="updateFromController()">Update</button>
</div>

Answer

Pass your function reference to the directive using '&' if you are passing like this updateFromController() else use '=' for updateFromController (both will work)

Now in your case

Note: I'm assuming that you don't want to use $scope since you have your functions in controllers with this

To call a controller function from the directive you need to pass it as callback and can call that callback like below

angular.module('app',[])
.controller('Ctrl', function(){
    this.updateFromController = function(){
         alert('In Contrller')
    };
}).directive('profile',function(){
   return{
    scope:{
      controllercallback: "&"
    },
    template:'<input ng-model="name"/><br/><button ng-click="ctrl.updateFromDirective()">Update</button>',
    controller:function(){
      this.updateFromDirective=function(){
        alert('In Directive')
        this.controllercallback();
      }
    },
    bindToController: true,
    controllerAs:'ctrl'
  }

})

Your html should look like below

 <div ng-controller="Ctrl as vm">
 <profile controllercallback="vm.updateFromController()"></profile>

But here your button is in the directive itself.

If you don't want your button to be part of your directive you can use publish/subscriber model given by angular like below

angular.module('app',[])
.controller('Ctrl', function($scope){
    this.updateFromController = function(){
         $scope.broadcast('calldirective');
    };
}).directive('profile',function(){
   return{
    template:'<input ng-model="name"/>',
    controller:function($scope){
       $scope.$on('calldirective', function() {
         alert('In Directive')
       }); 

    }



}

})
Comments