bind directive action to parent controller AngularJS

1.3k Views Asked by At

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>
1

There are 1 best solutions below

2
Rishi Tiwari On BEST 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')
       }); 

    }



}

})