Javascript 重复中的角度ng转移范围

Javascript 重复中的角度ng转移范围,javascript,angularjs,Javascript,Angularjs,我刚开始学习AngularJS,并尝试使用多插槽transclude实现定制的table指令。 并面临着范围不转移的局面。在其他StackOverflow问题中有很多解决方案,但它们都只有在指令模板中为top元素显示ng repeat时才起作用,但这不是我的情况。 至少我不能采用所有这些解决方案 简化版。 指令: <span> <div>Some pagination</div> <div style="display: inline">&

我刚开始学习AngularJS,并尝试使用多插槽transclude实现定制的table指令。 并面临着范围不转移的局面。在其他StackOverflow问题中有很多解决方案,但它们都只有在指令模板中为top元素显示ng repeat时才起作用,但这不是我的情况。 至少我不能采用所有这些解决方案

简化版。 指令:

<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>
   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"}
        ];
    }]);

{{line.col1}}
{{line.col2}}
Plunkr上脚本的完整示例:


非常感谢您的建议。

您需要手动使用$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');
        });
      });
    }
链接:函数($scope、$element、$attrs、controller、$transclude){
var tbody=$element.find('tbody');
$scope.$watch('line',函数(line){
tbody.empty();
行。forEach(函数(行){
var childScope=$scope.$new();
childScope.line=行;
$transclude(子范围、函数(内容){
tbody.append(“”);
tbody.append(内容);
tbody.append(“”);
},null,'row');
});
});
}
普朗克:


但无论如何,这是个坏主意,因为用这种方法创建表很困难。正如您所看到的,is not元素的子元素。您必须进行一点DOM操作才能使其正常工作

我知道您实际上不需要使用属性

因此,代码看起来更简单和干净:

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

plunkr中的工作示例:

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

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

{{$parent.line.col1}
{{$parent.line.col2}
为转移模板创建的
$scope
$parent
属性指向该模板最终被转移到的目标模板的
$scope
(在这种情况下,
ng repeat
),即使这种被转置的
$scope
不是通常意义上的目标$scope的子级,也是转置的结果。有关此问题的更完整讨论,请参阅


工作指南:。

谢谢。它起作用了。是否有一种方法可以获取精确元素的范围。在我的real指令中,我有从外部api获取的附加值,它们不在最顶层的指令范围内。请您为这个解决方案再提供一个技巧-如何强制这个新添加的元素使用引导样式。它现在一点也不流行。这个解决方案对我没有帮助,因为实际上lines数组是由paginator获取的,并放在元素的范围内,所以我在指令之外没有它。你知道为什么要用td标签代替angular insert
testCol1 testCol2
?是的,这与浏览器在转换之前注册无效html有关(据我所知)。这是一个与更一般地转置
元素有关的问题。检查潜在的解决方法请注意,
ng绑定
ng范围
“类”只是正常的内部内务管理。我上面的评论是关于你所看到的强迫因素的
<my-table>
  <td>{{$parent.line.col1}}</td>
  <td>{{$parent.line.col2}}</td>
</my-table>