javascript - AngularJS ng-repeat 在 $compiled 指令中多次应用

标签 javascript angularjs angularjs-directive angularjs-ng-repeat

我已经编写了一个动态为元素创建弹出框的指令:

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 在任何迭代中都会应用多次:

enter image description here

可以看到,本应只包含3个元素的迭代实际上包含了3*3个元素。该指令恰好为 3 个元素创建了弹出窗口,所以我想这就是我的错误所在。我如何确保在每个弹出窗口中,ng-repeat 只被调用一次?

最佳答案

问题

由于当您引导 Angular 应用程序(在页面加载时)时 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-repeats 中的每一个都会被触发,生成 3 个相同的副本,总共 9 个。

解决方案

将弹出窗口模板保存在一个单独的文件中,这样它就不会在页面加载时被编译。然后您可以使用 $templateCache 加载它服务。

一般来说,只要确保您没有多次编译您的 HTML。

关于javascript - AngularJS ng-repeat 在 $compiled 指令中多次应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26578446/

相关文章:

javascript - 将对象数据引用到另一个对象 -> object.property.OTHEROBJECT.PROPERTY.length

javascript - 使用 Three.js 按顺序对立方体进行动画处理

html - Angularjs 中嵌套数组的幻灯片

javascript - Angularjs指令点击元素

javascript - 所有字段编辑的单个编辑超链接选项

javascript - 如何将特定行的 Javascript 写入 Jquery 语法?

javascript - 将函数重写为异步

javascript - 为什么我的指令不能与 ng-bind-html 指令一起使用?

javascript - 溢出内容导致去除边框(CSS 和 AngularJS)

javascript - Angular.js - 向指令发出周期性事件