angular js:从指令调用父控制器方法

时间:2014-12-26 16:23:44

标签: javascript angularjs angularjs-directive

我使用树状网格插件(来自此链接:https://github.com/khan4019/tree-grid-directive

我自定义了它的模板:

.directive('treeGrid', [
    '$timeout', function($timeout) {
      return {
        restrict: 'E',
        template: 
          "<div class=\"table-responsive\">\
            <table id=\"policies\" class=\"table table-striped\">\
                <colgroup>\
                    <col width=\"10%\" />\
                    <col width=\"70%\" />\
                    <col width=\"1%\" />\
                    <col width=\"1%\" />\
                </colgroup>\
                <thead>\
                    <tr>\
                        <th>Category</th>\
                        <th>Content</th>\
                        <th></th>\
                        <th></th>\
                        <th></th>\
                    </tr>\
                </thead>\
                <tbody>\
                    <tr ng-repeat=\"row in tree_rows | filter:{visible:true} track by row.branch.uid\" ng-class=\"'level-' + {{ row.level }} + (row.branch.selected ? ' active':'')\">\
                    <td class=\"text-primary\"><a ng-click=\"user_clicks_branch(row.branch)\"><i ng-class=\"row.tree_icon\"ng-click=\"row.branch.expanded = !row.branch.expanded\"class=\"indented tree-icon\"></i></a>\
                    <span class=\"indented tree-label\" ng-click=\"user_clicks_branch(row.branch)\"> {{row.branch[expandingProperty]}}</span></td>\
                    <td ng-bind-html=\"row.branch[colDefinitions[2].field]\"></td>\
                    <td> <a href=\"javascript:void(0)\" ng-click=\"editContent(row.branch)\" data-toggle=\"modal\" data-target=\"#new-content\" class=\"action\"><i class=\"glyphicon glyphicon-edit\"></i></a> </td>\
                    <td> <a ng-click=\"deleteContent(row.branch.Id)\" class=\"action\"><i class=\"glyphicon glyphicon-remove-circle\"></i></a> </td>\
                    </tr>\
                </tbody>\
            </table>\
        </div>",
        replace: true,
        scope: {
          treeData: '=',
          colDefs:'=',
          expandOn:'=',
          onSelect: '&',
          deleteContent: '&',
          editContent: '&',
          initialSelection: '@',
          treeControl: '='
        },

和这样的控制器:

.controller('ContentCtrl', ['$http', '$scope', '$location', '$localStorage', 'authService', 'settings', function ($http, $scope, $location, $localStorage, authService, settings) {

  $scope.deleteContent = function(){
      console.log("delete");

    };
  }]);

并查看:

<tree-grid tree-data="policies"></tree-grid>

但是当我点击我的删除链接时,我什么都没得到,它没有进入控制器范围功能(

但为什么呢?我做错了什么?

我可以用脏的方式写这个函数在指令中,但这是一个坏主意((

如何解决?

2 个答案:

答案 0 :(得分:1)

由于treeGrid指令使用了隔离范围,因此它不能&#34;参见&#34; deleteContent,除非您通过模板传递它。

要修复,您需要在模板中定义指令时传递函数:

<tree-grid tree-data="policies" delete-content="deleteContent(branch)"></tree-grid>

该函数可以采用当前范围定义的任何值。这是分支。这可以通过在指令的模板中执行以下操作从隔离范围传递:

...
<td> <a ng-click=\"deleteContent({branch: row.branch})\" class=\"action\"><i class=\"glyphicon glyphicon-remove-circle\"></i></a> </td>\
...

我正在传递整个分支而不仅仅是id。这是在指令中使用的特殊语法,它将&隔离范围值并将branch参数(在树网格指令定义中使用)绑定到指令模板中的row.branch。注意:树网格中的branch必须与指令模板中使用的对象的属性名称匹配(例如{分支:row.branch})。

这是将fiddle传递给指令的deleteContent。单击链接时,它会记录到控制台。

如果这只是对指令保持静态的功能,您可以将它放入指令中的链接函数中:

指令内部:

link: function (scope, element, attrs) {
   //...
   scope.deleteContent = function () {
       console.log("Content deleted");
   }
   //...
}

答案 1 :(得分:0)

您可以研究AngularJS event知识。关键词是$broadcast(name, args);$emit(name, args);$on(name, listener);

关于您的问题,您可以使用此解决方案:

控制器:

.controller('ContentCtrl', ['$http', '$scope', '$location', '$localStorage', 'authService', 'settings', function ($http, $scope, $location, $localStorage, authService, settings) {

    $scope.deleteContent = function(){
        console.log("delete");
        $scope.$broadcast('deleteContentEvent',yourParams...);
    };
}]);

指令:

.directive('treeGrid', [
    '$timeout','$rootScope', function($timeout,$rootScope) {
     $rootScope.$on('deleteContentEvent',function(event,yourParams...){
         // do delete
     });
     ...