如何从指令调用控制器函数?

时间:2014-05-13 16:26:29

标签: angularjs angularjs-scope angular-ui angular-ui-bootstrap

如何从指令调用控制器函数?或者如何从控制器访问指令ng-model? 例如。我使用angular ui bootstrap time组件,当时间改变时我需要通知控制器中的调用函数。 我认为它通常是组件之间双向通信的典型用例。

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);
  };

};

3 个答案:

答案 0 :(得分:3)

我的建议是使用$emit而不是直接在你的指令中调用控制器的方法。

指令应该始终是独立的组件,如果在指令内部有一个来自控制器的方法(在指令之外),这将在我的指令和控制器之间创建一个依赖关系,当然这将迫使一个人不能没有对方存在。

如果我必须将设计原则应用于指令,则它将是SOL in SID,单一责任原则。指令应该能够封装和独立工作。

在我的控制器上,使用$on捕获事件,如:

$scope.$on("ValueChanged", function(event, ars){
   ... //your event has been triggered.    
});

答案 1 :(得分:3)

这是一个骨架应用程序,演示了如何在使用隔离范围避免紧密耦合(增强可重用性)的同时从指令调用父控制器函数:

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

要关注的是在指令的&设置中使用scope: { ... }符号。在这种情况下,它使您能够在HTML中的指令声明的alert属性中命名控制器函数。

然后可以从指令的模板中调用该函数。

在学习Angular中的指令时,使用隔离范围是一个常见的痛点,但是值得花些时间来解决这个问题。

关于&的使用,我发现this video特别有帮助。

答案 2 :(得分:0)

是emit / on作品还补充说,当控制器之间没有父/子层次结构时,它需要将$ rootScope注入用户控制器。