我们假设我有2个指令:外部和内部。在第一个指令中,我有一些数据,我想在其中插入带有ng-repeat的第二个指令。所以我的指令看起来像:
outer.js
directive('outer', function($compile) {
return {
restrict: 'E',
template: '<div class="options"></div>',
scope: true,
bindToController: {
options: '='
},
link: function(scope, element) {
var list = $(element).find('.options');
// Here we dynamically insert html for second directive
$('<inner><span ng-bind="$select.getValue(item)"></span></inner>').appendTo(list);
$compile(list.contents())(scope);
},
controllerAs: '$select',
controller: function($rootScope) {
this.items = ['aaa', 'bbb'];
this.getValue = function(item) {
$rootScope.log += '\n' + item;
return item;
};
}
};
}
inner.js
directive('second', function($compile) {
return {
restrict: 'E',
require: '^first',
replace: true,
transclude: true,
template: '<ul><li><span></span></li></ul>',
link: function(scope, element, attrs, $select, transclude) {
var choices = $(element.find('li')[0]);
choices.attr('ng-repeat', 'item in $select.items');
var inner = $(choices.find('span')[0]);
transclude(scope, function(clone) {
inner.append(clone);
});
$compile(choices)(scope);
}
};
});
所以,在我的例子中,在每个$ digest循环中,$ select.getValue应该被调用两次:for&#39; aaa&#39;并为&#39; bbb&#39;。但实际上它调用了3次,第一次调用undefined,但我不明白为什么
有什么想法吗?
参见示例:
var myApp = angular.module('myApp', []);
myApp.directive('outer', function($compile) {
return {
restrict: 'E',
template: '<div class="options"></div>',
scope: true,
bindToController: {
options: '='
},
link: function(scope, element) {
var list = $(element).find('.options');
$('<inner><span ng-bind="$select.getValue(item)"></span></inner>').appendTo(list);
$compile(list.contents())(scope);
},
controllerAs: '$select',
controller: function($rootScope) {
this.items = ['aaa', 'bbb'];
this.getValue = function(item) {
$rootScope.log += '\n' + item;
return item;
};
}
};
})
.directive('inner', function($compile) {
return {
restrict: 'E',
require: '^outer',
replace: true,
transclude: true,
template: '<ul><li><span></span></li></ul>',
link: function(scope, element, attrs, $select, transclude) {
var choices = $(element.find('li')[0]);
choices.attr('ng-repeat', 'item in $select.items');
var inner = $(choices.find('span')[0]);
transclude(scope, function(clone) {
inner.append(clone);
});
$compile(choices)(scope);
}
};
});
&#13;
.log {
white-space: pre;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body ng-app="myApp">
<span class="log" ng-bind="log"></span>
<outer></outer>
</body>
&#13;