AngularJS ng-repeat 在 $compiled 指令中多次应用 [英] AngularJS ng-repeat applied multiple times in $compiled directive

查看:17
本文介绍了AngularJS ng-repeat 在 $compiled 指令中多次应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个指令,为一个元素动态创建一个弹出框:

app.directive('popover', function($compile, $timeout){返回 {链接:函数(范围,元素,属性){$超时(功能(){//抓取模板var tpl = $(element).find('.popover-template')//抓取模板的弹出部分var 模板 = {//$compile( $(element).siblings(".pop-content").contents() )(scope)标题:tpl.find('.template-title').contents(),内容:tpl.find('.template-content').contents()};//用角度渲染模板var content = $compile(template.content)(scope);var title = $compile(template.title)(scope);$(元素).popover({html:对,位置:正确",内容:内容,标题:标题});范围.$digest()});}};});

在应用程序中它看起来像这样:

点击我;<div ng-hide="true" class="popover-template"><div class="template-title"><strong>{{ x.name }} 和 {{ y.name }}</strong>

<div class="template-content"><div>[1,2,3]中的<pre>f</pre><div ng-repeat="f in [1,2,3]">item {{ f }}, index {{ $index }}

弹出框已创建并显示.标题也能正常工作.但是,ng-repeat 在任何迭代中都会应用多次:

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

解决方案

问题

由于在您引导 angular 应用程序(在页面加载时)时 popover-template 元素已经在文档中,因此它已经被编译过一次.ng-repeat 元素被替换为 3 个新元素:

<div ng-repeat="f in [1,2,3]">item {{ f }}, index {{ $index }}</div><!-- 替换--><div ng-repeat="f in [1,2,3]">项目1,索引0</div><div ng-repeat="f in [1,2,3]">项目2,索引1</div><div ng-repeat="f in [1,2,3]">项目3,索引2</div>

当你在链接函数中再次编译它时,3 个 ng-repeat 中的每一个都会被触发,制作 3 个相同的副本,总共 9 个.

解决办法

将您的 popover-template 保存在一个单独的文件中,这样它就不会在页面加载时编译.然后,您可以使用 $templateCache 服务加载它.

一般来说,只要确保不要多次编译 HTML.

I've written a directive that dynamically creates a popover for an element:

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()
            });

        }

    };
});

In application it looks like this:

<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>

The popover is created and displayed. The title works correctly as well. However, ng-repeat is applied multiple times in any iteration:

As you can see, the iteration that should only include 3 elements in fact includes 3*3 elements. The directive creates popovers for exactly 3 elements, so I guess that's where my mistake lies. How can I make sure that within each popover, ng-repeat is only called once?

解决方案

The problem

Since the popover-template element is already in the document when you bootstrapped the angular application (at page load), it has already been compiled once. The ng-repeat element is replaced with 3 new elements:

<!-- 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>

When you compile it again in the link function, each of the 3 ng-repeats is triggered, making 3 identical copies, 9 total.

The solution

Keep your popover-template in a separate file so it is not compiled on page load. You can then load it with the $templateCache service.

In general, just make sure you don't compile your HTML multiple times.

这篇关于AngularJS ng-repeat 在 $compiled 指令中多次应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆