在彼此嵌套自定义指令时,如何防止 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>
这个问题紧接着我之前提出的关于让这些指令起作用的问题:
我的 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>