我编写了一个动态创建元素弹出窗口的指令:
app.directive('popover', function($compile, $timeout){
return {
link: function(scope, element, attrs) {
$timeout(function() {
// grab template
var tpl = $(element).find('.popover-template')
// grab popover parts of template
var template = {
//$compile( $(element).siblings(".pop-content").contents() )(scope)
title: tpl.find('.template-title').contents(),
content: tpl.find('.template-content').contents()
};
// render template with angular
var content = $compile(template.content)(scope);
var title = $compile(template.title)(scope);
$(element).popover({
html: true,
placement: "right",
content: content,
title: title
});
scope.$digest()
});
}
};
});
在应用程序中它看起来像这样:
<span popover>Click me</span>
<div ng-hide="true" class="popover-template">
<div class="template-title">
<strong>{{ x.name }} and {{ y.name }}</strong>
</div>
<div class="template-content">
<div>
<pre>f in [1,2,3]</pre>
<div ng-repeat="f in [1,2,3]">
item {{ f }}, index {{ $index }}
</div>
</div>
</div>
</div>
创建并显示弹出窗口。标题也正常工作。但是,在任何迭代中都会多次应用 ng-repeat :
如您所见,实际上应该只包含3个元素的迭代包括3 * 3个元素。该指令为3个元素创建了弹出窗口,所以我想这就是我的错误所在。如何确保在每个popover中ng-repeat
只被调用一次?
答案 0 :(得分:0)
由于popover-template元素在引导角度应用程序时(在页面加载时)已经在文档中,因此它已经编译了一次。 ng-repeat元素被3个新元素替换:
<!-- original -->
<div ng-repeat="f in [1,2,3]">item {{ f }}, index {{ $index }}</div>
<!-- replaced -->
<div ng-repeat="f in [1,2,3]">item 1, index 0</div>
<div ng-repeat="f in [1,2,3]">item 2, index 1</div>
<div ng-repeat="f in [1,2,3]">item 3, index 2</div>
当你在链接功能中再次编译它时,每个3 ng重复被触发,制作3个相同的副本,总共9个。
将popover-template保存在单独的文件中,以便在页面加载时不编译它。然后,您可以使用$templateCache服务加载它。
通常,只需确保不要多次编译HTML。
答案 1 :(得分:-1)
使用已编译的html作为弹出模板,使用$ http或templateCache加载模板。
HTML:
<span popover>Click me</span>
<script type="text/ng-template" id="popover.html">
<div class="popover-template">
<div class="template-title">
<strong>{{ x.name }} and {{ y.name }}</strong>
</div>
<div class="template-content">
<div>
<pre>f in [1,2,3] track by $index</pre>
<div ng-repeat="f in [1,2,3]">
item {{ f }}, index {{ $index }}
</div>
</div>
</div>
</div>
</script>
Javascript:
angular.module('app',[]).directive('popover', function($compile, $timeout, $templateCache){
return {
link: function(scope, element, attrs) {
$timeout(function() {
// grab the template (this is the catch)
// you can pass the template name as a binding if you want to be loaded dynamically
var tpl = angular.element($templateCache.get('popover.html'));
// grab popover parts of template
var template = {
title: tpl.find('.template-title').contents(),
content: tpl.find('.template-content').contents()
};
// render template with angular
var content = $compile(template.content)(scope);
var title = $compile(template.title)(scope);
$(element).popover({
html: true,
placement: "right",
content: content,
title: title
});
scope.$digest()
});
}
};
});
另外,我用一个工作示例制作了这个羽毛球:http://embed.plnkr.co/IoIG1Y1DT8RO4tQydXnX/