我正在尝试构建2个自定义指令my-tile和my-tile-item。
“my-tile”是接受数据数组参数的主要指令。
“my-tile-item”表示“my-tile”中的单个图块。
但my-tile-item控制器的btnOkClick()方法不起作用。
代码:
https://codepen.io/anon/pen/zdWgVG
HTML:
<div my-tile tiles="mainCtrl.tiles"></div>
my-tile模板:
<script type="text/ng-template" id="myTile.html">
<div my-tile-item ng-repeat="tileItem in myTileCtrl.tiles" class="my-tile">
<div>{{tileItem.id}}</div>
<button ng-click="myTileItemCtrl.btnOKClick()">OK</button>
</div>
</script>
my-title指令:
angular.module('app').directive('myTile',
[
myTile
]);
function myTile() {
return {
restrict: 'AE',
scope: {
tiles: '='
},
controller: ['$scope', MyTileController],
controllerAs: 'myTileCtrl',
templateUrl: 'myTile.html',
link: function (scope, iElement, iAttrs) {
console.log('abc');
}
};
function MyTileController($scope) {
var ctrl = this;
ctrl.tiles = $scope.tiles;
}
}
my-tile-item指令:
angular.module('app').directive('myTileItem',
[
myTileItem
]);
function myTileItem() {
return {
restrict: 'AE',
scope: {
},
controller : ['$scope', MyTileItemController],
controllerAs : 'myTileItemCtrl',
link: function (scope, iElement, iAttrs) {
}
};
function MyTileItemController($scope) {
var ctrl = this;
ctrl.btnOKClick = function () {
alert('OK Clicked'); // ********* does NOT work *************
}
}
}
答案 0 :(得分:2)
它按预期工作。由于my-tile-item
指令具有自己的独立范围和自己的控制器并不意味着,指令范围将应用于该元素。当指令有自己的template
或transcluded content
时,指令的范围将使用element进行编译。因此,在my-title-item
指令中,您没有template
,这就是为什么指令不会将指令范围应用于托管它的元素。
要解决您的问题,您可以在从myTileItemCtrl
指令生成内部模板后,在元素上使用my-title-item
范围。然后,您可以考虑将item
作为范围绑定从my-title-item
指令传递给my-tile
。
<script type="text/ng-template" id="myTile.html">
<div ng-repeat="tileItem in myTileCtrl.tiles" class="my-tile">
<my-tile-item item="tileItem"></my-tile-item>
</div>
</script>
my-item指令
function myTileItem() {
return {
restrict: 'AE',
scope: {
item: '<'
},
template: `
<div>{{item.id}}</div>
<button ng-click="myTileItemCtrl.btnOKClick()">OK</button>
`,
//...
}
}
通过上面的模板结构,你也实现了Smart and Dumb Component Pattern
,其中父亲几乎负责主要责任,而子女只接受绑定并在视图中呈现它。
答案 1 :(得分:0)
(function () {
'use strict';
angular.module('app').directive('myTileItem',
[
myTileItem
]);
function myTileItem() {
return {
restrict: 'AE',
link: function (scope, iElement, iAttrs) {
scope.btnOKClick = function () {
alert('OK Clicked');
}
}
};
}
})();
将btnOnClick移动到tileItem指令的链接功能,并删除范围:{}它将开始工作。并将<button ng-click="mytileItemCtrl.btnOKClick()">OK</button>
更改为<button ng-click="btnOKClick()">OK</button>
答案 2 :(得分:0)
你有一些问题。
我已经改变了您的代码,现在它正在工作:https://codepen.io/anon/pen/jLxNvE
第一个错误的修复可能是删除item指令中的隔离范围,只需删除item指令的块scope
即可。
通过这种方式,您的item指令将访问父级的范围,并可以覆盖该范围,添加新属性(作为您的函数)。
但这是错误的解决方案。
遵循最佳方法,而不删除项目指令中的孤立范围
您没有为item指令定义模板。您应该为您尝试实现的目标添加模板,因为如果您隔离范围,那么您的控制器只能在该指令的模板中访问,而无需查看父级的范围。没有相应的模板,该功能无法在那里调用。
然后在这些情况下最好的做法是你应该在item指令定义中提供一个scope参数,这实际上就是item(我用双向数据绑定做了但我不知道你想要什么do,所以根据您的要求更改绑定)。
这样一切都会正常。