【问题标题】:Repeat and insert directives重复和插入指令
【发布时间】:2015-04-13 21:24:10
【问题描述】:

我有 3 个不同的指令,<one><two><three>

我想遍历它们的 id 并将它们插入到 ng-repeat 中

<ul>
    <li ng-repeat="panel in panels">
        <panel>
            <!-- panel.id would give me "one", "two" etc. -->
            <!-- First insert <one> then <two> etc -->
        </panel>
    </li>
</ul>

我想要实现的结果 html 将是:

<ul>
    <li>
        <panel>
            <one></one>
        </panel>
    </li>
    <li>
        <panel>
            <two></two>
        </panel>
    </li>
    <li>
        <panel>
            <three></three>
        </panel>
    </li>
</ul>

因为每个都有它的模板:

<ul>
    <li>
        <div class="panel">
            <div id="one">
            </div>
        </div>
    </li>
    <li>
        <div class="panel">
            <div id="two">
            </div>
        </div>
    </li>
    <li>
        <div class="panel">
            <div id="three">
            </div>
        </div>
    </li>
</ul>

我不知道该怎么做?这可能吗?我必须ng-compile 才能在指令中包含指令吗?

我应该只使用一个指令并使用ng-switch吗?

我错过了更直接的方法吗?

我知道这行得通:

创建一个&lt;panel-content&gt; 指令。

我将它包含在 &lt;panel&gt; 指令中:

制作一个

<ng-switch="panel.id">
    <ng-switch-when="one">
    <ng-switch-when="twp">
    <ng-switch-when="three">
</ng-switch>`

但是看起来很麻烦。

【问题讨论】:

  • 这些指令有何不同 - 完全不同?
  • 你能告诉我你的panels详情
  • @JonEgerton 是的,为了这个问题,是的,完全。
  • @RameshRajendran 我无法向您展示实际代码。但它没有什么特别的,一个正常的指令。如果对可能影响您回答的问题有疑问,请详细告诉我。
  • 每个&lt;panel&gt; 是否需要渲染三个&lt;li&gt; 或者问题只是取决于您要编译一个指令或另一个指令的哪个ID?

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


【解决方案1】:

我通常这样做的方式是使用一个指令来选择链接函数中的特定指令。这可以防止所有 ng-switch 膨胀。

html

<panel type='one'></panel>
<panel type='two'></panel>

js

angular.module('app').directive('panel', ['$compile', '$injector', function ($compile, $injector) {
    return {
        restrict: 'E',
        scope: {
            type: '='
        },
        link: function ($scope, element, attrs, vm) {
            var template;
            switch($scope.type){
                case 'one':
                    template = '<one></one>';
                    break;
                case 'two':
                    template = '<two></two>';
                    break;
            }
            element.html(template);
            $compile(element.contents())($scope);
        }
    };
}]);

这是一个展示这个的小提琴:http://jsfiddle.net/7cufjqs3/1/

【讨论】:

  • 这很有趣,让我看看它如何应用于我的实际代码,我会回复你。
  • 我确实认为这是一个很好的解决方案,但 HTML 现在更难阅读,因为您将开关隐藏在指令中而不是在 HTML 中编写。
  • 我想知道是否出于性能原因最好在发布链接功能中添加开关?你怎么看? compile : function () { return { post : \\ 你的 switch 函数 \\ }}
  • 不使用ng-switch的主要原因是我很确定它会创造更多的观察者。因此,如果您不打算即时切换要创建的控件类型,那么通过仅运行一次的链接功能执行此操作应该会减少内存使用量。但你是对的,它确实使 html 更难阅读。
  • @StefanvandeVooren 我相信帖子链接功能和普通旧链接功能是一回事。请参阅本·纳德 (Ben Nadel) 的这篇文章。 bennadel.com/blog/…
【解决方案2】:

如果您愿意在指令和panel 元素之间使用额外的 div,我创建了一个动态指令,它对元素的名称一无所知,并动态创建它:

用法

<li ng-repeat="panel in panels">       
    <panel>
       <dynamic-directive element="panel.id"></dynamic-directive>
    </panel>
</li>

指令

myApp.directive('dynamicDirective', function($compile) {
    return {
        restrict: "E",
        replace: true,
        template: "<div></div>",
        scope: {
            element: "="
        },

        link: function(scope, element, attrs) {
            var elm = '<' + scope.element + '></' + scope.element + '>';
            element.html(elm);
            $compile(element.contents())(scope);
        }
    }
});

Fiddle

【讨论】:

    【解决方案3】:

    我认为 switch 是最好的方法,因为它在您的 html 中最易读

    <ul>
        <li ng-repeat="panel in panels">
            <panel ng-switch on="panel.id">
              <div ng-switch-when="one"><one>1</one></div>
              <div ng-switch-when="two"><two>2</two></div>
              <div ng-switch-when="three"><three>3</three></div>
            </panel>
        </li>
    </ul>
    

    http://plnkr.co/edit/ygy6coKCyQNGBoKmSES0?p=preview

    【讨论】:

    • 那不是想要的输出,应该是&lt;panel&gt;&lt;one&gt;&lt;/one&gt;&lt;/panel&gt;
    • 输出为 '
    • ' 等...是的,由于额外的开关和额外的面板指令,面板和“one”指令之间有一些额外的 div。为什么这对你来说是个问题?
  • 哦,抱歉,我错过了 ng-switch。我其实有点喜欢这个,谢谢,我试试看。
  • 猜你喜欢
    相关资源
    最近更新 更多
    热门标签