在彼此嵌套自定义指令时,如何防止 ngClick 通过父指令

How can I prevent ngClick to go through parent directive when nesting custom directives inside each other

这个问题紧接着我之前提出的关于让这些指令起作用的问题:

我的 Html 看起来像这样:

<div ng-grid ng-collection="entries" ng-collection-headings="headings" ng-button-click="theAction(inp)">
    <div ng-checkbox-column></div>
</div>

它生成如下所示的 Html:

<div ng-grid="" ng-collection="entries" ng-collection-headings="headings" ng-button-click="theAction(inp)" class="ng-isolate-scope">
    <table class="table table-bordered">
        <thead>
            //Truncated for brevity
        </thead>
        <tbody>
            <tr id="item0" ng-repeat="item in ngCollection" class="ng-scope">
                <td ng-checkbox-column="">
                    <label>
                        <input type="checkbox" ng-model="item.checked" ng-click="tempButtonClicked()" class="ng-pristine ng-untouched ng-valid"> From the checkbox directive.
                    </label>
                </td>
            </tr>
            //Truncated for brevity
        </tbody>
    </table>
</div>

我遇到的问题是无法从 myCtrl 控制器[=80] 分配 ng-checkbox-column 指令 的 ng-click 事件=] 在 ng-grid 指令 之外。这是因为我为 ng-grid 指令 创建了一个隔离范围,而 ng-checkbox-column 指令 共享 ng-grid 指令.

有办法解决这个问题吗?

我有什么选择才能让它工作?

我使用事件是唯一的选择吗?

我为 ng-grid 指令 创建隔离范围的原因是它可以在同一个控制器中多次使用。因此我无法共享 myCtrl 控制器.

的范围

这是一个显示问题的 plunker:

Plunker with working dynamic grid, but limited ng-click

查看 plunker,您可以单击按钮以查看与 "scopes" 相关的单击发生的位置。 我希望复选框触发自己的事件并更新状态,而无需通过 ng-grid 指令。

目前我正在用这个处理 ng-click:

ng-click='tempButtonClicked()'

并且在 ng-checkbox-column 控制器中:

$scope.tempButtonClicked = function () {
  var val = "From the checkbox directive";
  $scope.buttonClicked(val);
};

其中 $scope.buttonClicked(val); 是对 ng-grid 指令的控制器中定义的函数的引用:

$scope.buttonClicked = function (inp) {
  if (typeof inp != 'undefined')
    inp = inp + ", through the grid directive.";
  else
    inp = "From the grid directive.";

    $scope.ngButtonClick({ inp: inp });
};

反过来,将其绑定到通过 ng-grid 指令 中定义的隔离作用域变量指定的函数,如:

scope: {
  ngButtonClick: "&"
},

我希望我所解释的是有意义的,并且有人可以对这个主题有更多的了解。

我想要的:

是一种将函数绑定到 ng-checkbox-column 指令的方法,这样我就可以在 myCtrl 控制器[=80= 中调用函数] 当它被点击时。

这是因为我可能在一个网格中有多个列模板,并根据单击的列执行不同的操作。

按照目前的工作方式,我必须在 ng-grid 指令中定义 x 数量的函数以与模板一起使用,这似乎是一种草率的做法。

我希望能够做到这一点:

<div ng-checkbox-column ng-click-action="someDefinedFunctionInMyCtrl()"></div>

生成这个:

<td ng-checkbox-column="">
    <label>
        <input type="checkbox" ng-model="item.checked" ng-click="someDefinedFunctionInMyCtrl()"> From the checkbox directive.
    </label>
</td>

使用表达式作为属性和 ng-transclude 使其工作:

http://plnkr.co/edit/3XmsE3d44v8O0AxOoUeF?p=preview

JS:

.directive("ngGrid", function () {
    return {
        [...]
        transclude: true, //added transclude
        template: function (element, attrs) {
            var children = element.html();
            children = children.trim().replace(/div/g, "td");
            var htmlText = [
              "<input type='button' ng-click='buttonClicked()'",
                " value='From the grid directive' />",
              "<table class='table table-bordered'>",
                "<thead><tr>",
                  "<th ng-repeat='heading in ngCollectionHeadings'>{{heading}}</th>",
                "</tr></thead>",
                //added ng-transclude
                "<tbody><tr id='item{{$index}}'",
                   " ng-repeat='item in ngCollection' ng-transclude>",
                  children,
                "</tr></tbody>",
              "</table>"
            ].join('');
            return htmlText;
        },
        [...]
    };
})

.directive("ngCheckboxColumn", function () {
    return {
        restrict: "A",
        scope: {
            //expression as an attribute
            myClick: '&'
        },
        [...]
        controller: function ($scope, $element) {
          $scope.tempButtonClicked = function () {
              var val = "From the checkbox directive";
              //call the expression (val will be available in the expression)
              $scope.myClick({val: val});
          };
        }
    };
})

HTML:

<div ng-controller="myCtrl">
    <div ng-grid ng-collection="entries"
         ng-collection-headings="headings" ng-button-click="theAction(inp)">
        <!-- added the my-click expression (use val here) -->
        <div ng-checkbox-column my-click="ctrl.theAction(val)"></div>
    </div>
    <p id="btnClickVal">{{actionVal}}</p>
    <input type="button" ng-click="theAction(fromParent)"
        value="From the parent controller" />
</div>