我有一个指令需要插入一个额外的指令依赖
关于一些模型价值。我在指令的[编辑]预链接阶段这样做。
parent指令设置了一个主机
孩子使用的方法和数据。因此,我有儿童指令
scope:true
。
在外部(或父项)指令上有一个单击处理程序方法。当我
点击这个,它会被解雇两次。我想知道为什么以及如何。现在的
只有这样我知道如何阻止它是通过调用event::stopImmediatePropagation()
但我怀疑我在这里做错了什么。
模板用法
<dashboard-box data-box-type="column with no heading">
<div class="card">
<div
ng-click="show($event)"
class="box-title item item-divider ng-binding is-shown"
ng-class="{'is-shown':showMe}">
<span class="box-title-string ng-binding">A/R V1</span>
</div>
<div class="box-content item item-text-wrap" ng-show="showMe">
<!-- plug appropriate dashbox here - in dashboard-box compile -->
<dashbox-column-with-no-heading>
<div>
SOME DATA...
</div>
</dashbox-column-with-no-heading>
</div>
</div>
</dashboard-box>
在仪表板框的指令中:
scope: {
boxType: "@"
},
pre: function preLink(scope, iElement, iAttrs, controller) {
// some crazy hardcoding - because find by tagname...replaceWith throws in ionic
var parent_div = angular.element(angular.element(iElement.children()[0]).children()[1]);
if (!parent_div) {
return; // programmer error in template??
}
var html_tag_name = d_table_type_to_directive_name.xl[iAttrs.boxType];
parent_div.append(angular.element( "<" + html_tag_name + ">" ));
$compile(iElement.contents())(scope); // angular idiom
}
在仪表板框的控制器中:
$scope.show = function($e){
$log.log("dashboard box show(), was=", $scope.showMe, $e);
if ($e) $e.stopImmediatePropagation(); // <<<<<<<<<<< without this, double-hits!!
$scope.showMe = ! $scope.showMe;
// etc
};
在dashbox-column-with-row-heading的指令中:
restrict: "E",
scope: true,
templateUrl: "dashbox-column-with-row-heading.tpl.html"
controller: function(){
// specialized UI for this directive
}
我正在使用ionicframework rc-1.0.0和angularjs 1.3.13。
答案 0 :(得分:4)
这里发生的是你正在双重编译/链接ng-click
指令:1)Angular第一次在编译阶段做到这一点 - 它遍历DOM并编译指令,首先是{{1} },然后它的子节点,以及dashboardBox
)和2) - 当您使用ngClick
进行编译时。
这是一个简化的示例 - demo - 可以重现您的问题:
$compile(element.contents())(scope)
并且<foo>
<button ng-click="doFoo()">do foo</button>
</foo>
指令是:
foo
您需要做的是转换内容。通过转换,Angular在编译指令时编译内容,并通过.directive("foo", function($compile) {
return {
scope: true,
link: {
pre: function(scope, element, attrs, ctrls, transclude) {
$compile(element.contents())(scope); // second compilation
scope.doFoo = function() {
console.log("foo called"); // will be called twice
};
}
}
};
});
函数使内容可用。
所以,不要再使用transclude
,而是使用已编译的 - 但尚未链接(直到你告诉它应该链接到什么) - 指令的内容。
使用下面的$compile
示例,情况如下:
foo