Angular ng-transclude范围重复

时间:2016-07-12 07:36:33

标签: javascript angularjs

我刚开始研究AngularJS并尝试使用多个插槽transclude实现自定义表指令。 并且面临范围未转移到转移的情况。其他StackOverflow问题中有很多解决方案,但所有这些问题只有在指令模板中才会起作用ng-repeat出现在top元素中,但这不是我的情况。 至少我不能采用所有解决方案。

简化版。 指令:

<span>
  <div>Some pagination</div>
  <div style="display: inline"><input type="text" placeholder="Search"/></div>
  <div style="display: inline">Some filters</div>

  <table>
    <tbody>
      <tr ng-repeat="line in lines" ng-transclude="row">
      </tr>
    </tbody>
  </table>

  <div>Some pagination again</div>
</span>

使用指令:

<my-table>
     <row>
          <td>{{line.col1}}</td>
          <td>{{line.col2}}</td>
      </row>
</my-table>

Plunkr上的脚本的完整示例: https://plnkr.co/edit/rg43ZdPMGHLBJCTLOoLC

非常感谢任何建议。

3 个答案:

答案 0 :(得分:1)

您需要手动使用$ transclude函数并为每一行创建新的子范围。除此之外,如果您正在使用隔离范围(并且您正在使用它),则需要将行传递给指令。 您的链接功能应如下所示:

link: function($scope, $element, $attrs, controller, $transclude) {
      var tbody = $element.find('tbody');

      $scope.$watch('lines', function (lines) {
        tbody.empty();

        lines.forEach(function (line) {
          var childScope = $scope.$new();
          childScope.line = line;

          $transclude(childScope, function (content) {
            tbody.append('<tr>');
            tbody.append(content);
            tbody.append('</tr>');
          }, null,  'row');
        });
      });
    }

Plunker:https://plnkr.co/edit/MLNZOmoQyMazgIpluMqO?p=preview

但无论如何,这是个坏主意,因为很难以这种方式创建表格。你可以看到孩子不是元素。你必须做一些DOM操作才能使它工作。

答案 1 :(得分:1)

在转换模板中直接引用$scope创建的ng-repeat对象的最简单且可能最干净的方法是通过$parent属性:

<my-table>
  <td>{{$parent.line.col1}}</td>
  <td>{{$parent.line.col2}}</td>
</my-table>

为转化模板创建的$parent的{​​{1}}属性指向最终转换此类模板的目标模板的$scope(在本例中为{{1}尽管这种被转换的$scope不是通常意义上的目标$范围的子节点,但是由于这种转换。有关此问题的详细讨论,请参阅this wonderful blog post

工作plunkr:https://plnkr.co/edit/LoqIMiQVZKlTt5epDnZF?p=preview

答案 2 :(得分:0)

我发现你并不需要使用属性

所以代码看起来更简单干净:

 <body ng-controller="tableCtrl">
   <h1>Table test</h1>
   <my-table lines="lines"></my-table>
 </body>

你的模板:

    <span>
      <div>Some pagination</div>
      <div style="display: inline"><input type="text" placeholder="Search"/></div>
      <div style="display: inline">Some filters</div>

      <table>
        <tbody>
          <tr ng-repeat="line in lines">
               <td>{{line.col1}}</td>
               <td>{{line.col2}}</td>
          </tr>
        </tbody>
      </table>

      <div>Some pagination again</div>
    </span>

和angular指令:

   angular.module('myApp', [])
    .directive("myTable", function() {
      return {
        restrict: 'E',
        transclude: true,
        scope: {
          lines:'=lines',
          api: '@'
        },
        templateUrl: "template.html",
      };
    })
    .controller("tableCtrl", ['$scope', function($scope) {
      $scope.lines = [
        {col1: "testCol1", col2: "testCol2"},
        {col1: "testCol11", col2: "testCol21"}
        ];
    }]);

plunkr中的工作示例:https://plnkr.co/edit/iMxRoD0N3sUXqmViHAQh?p=preview