处理指令不同部分的Angular模板的最佳方法

时间:2013-10-09 21:02:52

标签: angularjs angularjs-directive angularjs-scope

我看到了在指令中使用嵌套模板的不同方法,但它们都没有很好用。至少我没有设法解决各种问题。

所以我的想法是什么 - 我需要创建一个可重用的指令,它由不同的逻辑部分组成(如页眉,页脚,菜单,操作栏,内容,选择器等)。我需要的是能够在HTML布局内部指定整个模板和不同部分的模板,如下所示:

<videoBoard>
    <header-template>{{heading}}</header-template>
    <menu-template><a ng-click="showVideo()"/></menu-template>
    <content>
         <a ng-href="{{item.link}}" ng-repeat="items">{{item.caption}}</a>
    </content>
<videoBoard>

基于此定义,将创建目标HTML布局,就像我直接在指令中指定它一样。我需要能够使用范围变量传递的HTML元素通过代码指定。

这样的事情。如果我们在这里没有指定一些模板,我们使用默认模板(单独定义或在整个模板的标记部分内定义)。像范围这样的所有东西,跟踪变化都应该有效。

那么如何做到最好?

1 个答案:

答案 0 :(得分:0)

我认为你的问题对于一个SO问题来说太宽泛了。如果您想问一个关于动态模板的单独问题,可以使用以下方法来替换项目... (fiddle)

<script type="text/ng-template" id="test.html">
    <h1>Template H1 for {{name}}</h1>
    This should replace everything, but the &lt;h1&gt;
    element can be overridden
</script>    

<div class="boxed">
    <parent>
        <h1>Hello, {{name}}</h1>
        This should say only the person's name
    </parent>
</div>

<div class="boxed">
    <parent>
        This should say whatever the default is
    </parent>
</div>

templatable templates

使用transcludecompile代替link,我们可以使用模板并仍然可以访问原始元素。 compile函数返回一个函数,类似于指令返回的普通link函数。它需要linker作为参数,这是一个你可以调用的函数,并提供另一个函数来访问原始元素(clone这里)。

    transclude: true,
    templateUrl: 'test.html',
    compile: function(element, attrs, linker) {
        // need to return linking function
        var parent = element.parent();
        return function($scope, $element, $attrs) {
            linker($scope, function(clone) {
                // 'clone' is a copy of the original elements in our 'parent' element
                var existing = $element.find('h1'); // in template
                if (existing.length == 1) {
                    // look for replacement h1 element specified in code
                    for (var i = 0; i < clone.length; i++) {
                        if (clone[i].tagName == "H1") {
                            // replace h1 element in template with specified
                            $element[0].replaceChild(clone[i], existing[0]);
                            break;
                        }
                    }
                }
            });
        }

这使用模板并完全替换parent标记之间的任何内容,但可以使用clone参数访问原始内容。在这里,我将h1元素(如果存在于原始元素中)并使用它来替换模板中的h1元素。语法有点搞笑,我希望我能做一个clone.find('h1')但是克隆似乎是我认为并且发现不起作用的JQLite对象数组。