Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call controller function from directive?

how to call controller function from directive? or howto access directive ng-model from controller? eg. I use angular ui bootstrap time component and when time change I need to notify calling function in controller. I think in general it's typical use case for two way communication between components.

appControllers.controller('mainCtrl', ['$scope', 
  function($scope) {

    $scope.changedTime = function(time) {
        alert(time);        
    }

 }]).directive('timePicker',['$http', function($http) {
  return {
    restrict: 'AE',    
    templateUrl: 'partials/time-picker.html',
    scope: true,
    controller: 'TimepickerDemoCtrl'        
  };
}]);


//partials/time-picker.html:
<span ng-controller="TimepickerDemoCtrl">              
   <timepicker ng-model="mytime" ng-change="changed()" hour-step="hstep" minute-step="mstep" show-meridian="ismeridian"></timepicker>              
</span>


//TimepickerDemoCtrl (copy from source):
var TimepickerDemoCtrl = function ($scope) {
  $scope.mytime = new Date();
  $scope.hstep = 1;
  $scope.mstep = 15;

  $scope.options = {
    hstep: [1, 2, 3],
    mstep: [1, 5, 10, 15, 25, 30]
  };

  $scope.ismeridian = true;
  $scope.toggleMode = function() {
    $scope.ismeridian = ! $scope.ismeridian;
  };

  $scope.update = function() {       
    var d = new Date();
    d.setHours( 14 );
    d.setMinutes( 0 );
    $scope.mytime = d;
  };

  $scope.changed = function () {
    console.log('Time changed to: ' + $scope.mytime);
  };

};
like image 686
mark small Avatar asked Aug 22 '26 16:08

mark small


1 Answers

Here is a skeleton app that demonstrates how you can call parent controller functions from directives while using isolate scope to avoid tight coupling (which enhances reusability):

JS:

angular.module('myApp', [])
.controller('MyController', function($scope){
  $scope.showAlert = function(value){
    alert('Called from directive: ' + value);
  };
})
.directive('myDirective', function(){
  return {
    restrict: 'E',
    scope: {
      alert: '&'
    },
    controller: function($scope){
      $scope.value = 'directive scope value';
    },
    template: '<button ng-click="alert({message: value})">Alert</button>'
  }
});

HTML:

<body ng-app="myApp" ng-controller="MyController">
  <my-directive alert="showAlert(message)"></my-directive>
</body>

Plunker using this code

The thing to focus on is the use of the & symbol in the scope: { ... } setting of the directive. In this case, it provide you with the ability to name the controller function in the alert attribute of your directive declaration in the HTML.

That function can then be called from the template of the directive.

Using isolate scope is a common pain point when learning about directives in Angular, but it is well-worth taking the time to wrap your head around.

Regarding the use of & in particular, I found this video to be especially helpful.

like image 156
Marc Kline Avatar answered Aug 27 '26 00:08

Marc Kline