AngularJS中指令和控制器的交互

时间:2015-07-06 14:18:12

标签: javascript angularjs

我想创建一个将自身显示为可折叠框的组件。 展开时,应显示已转换的内容;当它被折叠时,它应该只显示它​​的标签。

myApp.directive('collapsingBox', function() {

  return {
    restrict: 'E',
    transclude: true,
    require: '^ngModel',
    scope: {
      ngModel: '='
    },
    template: '<div ng-controller="CollapseController" class="collapsingBox"><div class="label">Title: {{ ngModel.title }}</div><br/><div ng-transclude ng-show="expanded">Test</div></div>',
    link: function($scope, element, attr) {
      element.bind('click', function() {
        alert('Clicked!');
        $scope.toggle();
      });
    }
  };

});

这个组件应该是可重用的和可嵌套的,所以我想管理一个控制器中的值(如“title”和“expanded”),该控制器在每次使用该指令时都会被实例化:

myApp.controller('CollapseController', ['$scope', function($scope) {
  $scope.expanded = true;

  $scope.toggle = function() {
    $scope.expanded = !$scope.expanded;
  };
}]);

这种“差不多”似乎有效: http://plnkr.co/edit/pyYV0MAikXThvMO8BF69

唯一不起作用的似乎是从链接期间绑定的事件处理程序访问控制器的范围。

link: function($scope, element, attr) {
  element.bind('click', function() {
    alert('Clicked!');
    $scope.toggle(); // this is an error -- toggle is not found in scope
  });
}
  1. 这是使用指令创建控制器的一个实例的正确(通常?)方式吗?
  2. 如何从处理程序访问toggle-Function?

1 个答案:

答案 0 :(得分:1)

您需要将控制器放在指令的ng-controller属性中,而不是在指令的模板上使用controller

return {
  restrict: 'E',
  transclude: true,
  require: '^ngModel',
  scope: {
    ngModel: '='
  },
  template: '<div class="collapsingBox"><div class="label">Title: {{ ngModel.title }}</div><br/><div ng-transclude ng-show="expanded">Test</div></div>',
  controller: 'CollapseController',
  link: function($scope, element, attr) {
    element.bind('click', function() {
      alert('Clicked!');
      $scope.toggle();
    });
  }
};

由于CollapseController的范围将是指令范围的子范围,这就是为什么toggle()不会出现在那里。