0

解释起来很复杂,但我会尽力。

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

这个例子按我的需要工作,我只是不喜欢我实现这个的方式。

我将尝试解释您在示例中看到的内容。

<repeater>

  <item name="Hello item">
    <h4>Hello</h4>
    <p>Lorem ipsum dolor sit amet</p>
  </item>

  <item name="Worlditem">
    <h4>World</h4>
    <em>Mauris elementum elementum enim at suscipit.</em>
  </item>

</repeater>

<item>指令应将自身“注册”repeateravailable_item. 它现在不应该显示。

<repeater>指令应该打印可用项目的菜单,并且在单击菜单项后,它应该将项目的模板添加到它的内容中。例如repeater模板可能看起来像这样:

<div>
  <ul>
    <li ng-repeat="item in available_items">
      <a href="javscript:;" ng-click="add2content(item)">{{item}}</a>
    </li>
  </ul>

  <div id="content">
    <div ng-repeat="item in content_items track by $index">
      <ng-include src="item"></ng-include>
    </div>
  </div>

</div>

那么在我的工作plnkr.co 示例中我不喜欢什么?

我不喜欢我必须包含<div ng-transclude></div>在 my 中repeater.html,否则<item>'s 将不再被编译。但我不需要在页面加载时打印项目——它们只是模板。我已将<items>模板设置为空字符串,但在源代码中我看到空<item>标签,我不喜欢这个..

实际上我不确定我不喜欢那里的什么,但感觉一切都在hard-coded那里,不是吗?

Ifrepeater的指令将按以下顺序编译:

  1. controller() - add2available() 函数将被注册
  2. 预链接()
  3. //现在是所有item指令,它们可以将自己注册到转发器
  4. 后链接()
  5. 模板() - 现在转发器更改它的模板,其中没有ng-transclude

我确定这是不可能的。而且我不确定我不喜欢我的代码中的哪些内容,但我希望您能看到其他改进我的代码的方法。

非常感谢!

PS我知道我可以用一些标签替换<item>指令,但我需要在我的示例中提供。<script type="text/ng-template" id=""><item>

4

1 回答 1

1

除了您不喜欢的部分(即虚拟标签和空标签)之外,这个plunkr可以实现您想要实现的目标。我还清理了一些技巧,比如在属性中存储 HTML、返回空模板、污染模板缓存......<transclude><item>

该解决方案的关键元素是使用该$transclude服务来编译和链接在嵌入内容中声明的指令。整个更新的脚本如下。

脚本.js

angular.module('repeaterApp', [])
  .directive('repeater', function() {
    return {
      restrict: 'E',
      transclude: true,
      scope: {},
      templateUrl: 'repeater.html',
      controller: function($scope, $element, $transclude) {
        var available_items = $scope.available_items = [];
        var content_items = $scope.content_items = [];

        $scope.add2content = function(item) {
          content_items.push(item);
        };

        $scope.add2available = function(item) {
          available_items.push(item);
        };

        $transclude($scope);
      }
    };
  })
  .directive('item', function($templateCache, $sce) {
    return {
      restrict: 'E',
      link: function(scope, element, attrs) {
        scope.add2available({
          name: element.attr('name'),
          html: $sce.trustAsHtml(element.html())
        });
      }
    };
  });

中继器.html

<div>
  <ul>
    <li ng-repeat="item in available_items">
      <a href="javscript:;" ng-click="add2content(item)">{{item.name}}</a>
    </li>
  </ul>

  <div id="content">
    <div ng-repeat="item in content_items track by $index" 
         style="background: #f4f4f4; padding: 5px; margin: 5px; clear: both;"
         ng-bind-html="item.html">
    </div>
  </div>
</div>

索引.html

<repeater>

  <item name="Hello item">
    <h4>Hello</h4>
    <p>Lorem ipsum dolor sit amet</p>
  </item>

  <item name="Worlditem">
    <h4>World</h4>
    <em>Mauris elementum elementum enim at suscipit.</em>
  </item>

</repeater>
于 2014-11-25T01:39:21.547 回答