这里我有一个ctrl
controllers.ctrl = function($scope){
$scope.trData = [
{name : 'elem1',children : []},
{name : 'elem2',children :
[{name : 'elem3',children : []}]
}
};
$scope.testFunction = function(tr){
console.debug(tr);
}
}
嵌套指令
directives.nested = function($compile){
restrict: 'E',
replace: false,
scope: {
tr: '=',
test : '&'
},
link: function(scope, element, attrs) {
scope.setActive = function(){
console.debug("A");
console.debug(scope.tr);
scope.test({tr:scope.tr});
console.debug("B");
};
var template = '<span data-ng-click="setActive();">{{tr.name}} - </span>';
if(scope.tr.children.length > 0){
template += '<ul><li data-ng-repeat="tr0 in tr.children">';
template += '<nested tr="tr0" test="test(tr)"></nested>';
template += '</li></ul>';
}
var newElement = angular.element(template);
$compile(newElement)(scope);
element.replaceWith(newElement);
}
当然,在我的模板中:
<ul>
<li data-ng-repeat="tr in trData">
<nested tr="tr" test="testFunction(tr)"></nested>
</li>
</ul>
当我点击elem1时,我已进入控制台:
A
{name : 'elem1',children : []}
B
如果我点击'elem3',我就
了A
{name : 'elem3',children : []}
{name : 'elem2',children : [{name : 'elem3',children : []}] }
B
函数testFunction被调用两次。我想用elem3只调用一次。
我相信有更好的方法可以做到这一点。
来自Banana-In-Black的小提琴:http://jsfiddle.net/T4uKf/
答案 0 :(得分:1)
尝试点击elem3:您将看到console.debug输出&#39;对象 {name:&#34; elem3&#34;,children:Array [0]&#39;而console.warn输出: 对象{名称:&#34; elem2&#34;,孩子:数组[1]我虽然会有&#34; elem3&#34; 输出两次。相反,我得到了&#34; elem3&#34;和&#34; elem2&#34;。你知道为什么吗? 会发生什么?
首先,我们先看一下生成的HTML和范围:
<!-- controller scope -->
<li data-ng-repeat=" tr in trData "> <!--1|-child scope -->
<span>elem2 - </span> <!--2 |-isolated scope -->
<ul> <!-- | -->
<li data-ng-repeat="tr0 in tr.children"><!--3 |-child scope -->
<span>elem3</span> <!--4 |-isolated scope -->
</li>
</ul>
</li>
范围内的变量如下:(|-
代表继承)
{ trData: [...] }
{ tr0: elem2 }
{ tr: elem2, test: function() }
{ tr0: elem3 }
{ tr: elem3, test: function() }
现在,根据official api docs,它讨论了孤立的范围变量:
&安培;或&amp; attr - 提供了一种在父作用域的上下文中执行表达式的方法。
*此功能由$parse
服务实施。
点击elem3
后,执行顺序为:(跳过日志部分。)
test({ tr: scope.tr })
使用Scope4
作为执行上下文
$parse('test(tr)')(Scope3, { tr: elem3 })
。Scope3
中调用它,因为$parse
在父范围内执行。test(tr)
使用Scope3
作为执行上下文
$parse('testFunction(tr)')(Scope1, elem3)
Scope1
中调用它,因为test()继承自Scope2
,而$parse
在父范围内执行。testFunction(tr)
使用Scope1
作为执行上下文
Scope1.tr
elem2
,因为elem3.tr
不存在。console.warn(elem2)
; 这就是这种情况......
*关于$ parse服务,您可以查看this。
我将console.log
更改为console.warn
,ang日志显示它只执行一次。
$scope.testFunction = function (tr) {
console.warn(tr);
}
打印两次
A
{name : 'elem3',children : []}
{name : 'elem2',children : [{name : 'elem3',children : []}] }
B
只是因为您在scope.setActive
和$scope.testFunction()