Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 添加具有ng repeat和嵌套循环的行_Javascript_Angularjs - Fatal编程技术网

Javascript 添加具有ng repeat和嵌套循环的行

Javascript 添加具有ng repeat和嵌套循环的行,javascript,angularjs,Javascript,Angularjs,我正在寻找一种向表中添加行的方法。我的数据结构如下所示: rows = [ { name : 'row1', subrows : [{ name : 'row1.1' }, { name : 'row1.2' }] }, { name : 'row2' } ]; table row1 row1.1 row1.2 row2 我想创建一个如下所示的表: rows = [ { name : 'row1', subrow

我正在寻找一种向表中添加行的方法。我的数据结构如下所示:

  rows = [
    { name : 'row1', subrows : [{ name : 'row1.1' }, { name : 'row1.2' }] },
    { name : 'row2' }
  ];
  table
     row1
     row1.1
     row1.2
     row2
我想创建一个如下所示的表:

  rows = [
    { name : 'row1', subrows : [{ name : 'row1.1' }, { name : 'row1.2' }] },
    { name : 'row2' }
  ];
  table
     row1
     row1.1
     row1.2
     row2
这有可能是重复的吗?如果不是,什么是“角度”的方法

编辑: 展平数组将是一个糟糕的解决方案,因为如果我可以迭代子元素,我可能会在单元格内使用不同的html标记、其他css类等。

是的,有可能:

控制器:

app.controller('AppController',
    [
      '$scope',
      function($scope) {
        $scope.rows = [
          { name : 'row1', subrows : [{ name : 'row1.1' }, { name : 'row1.2' }] },
          { name : 'row2' }
        ];

      }
    ]
  );
function($scope) {
  $scope.rows = [
    { name : 'row1', subrows : [{ name : 'row1.1' }, { name : 'row1.2' }] },
    { name : 'row2' }
  ];

  $scope.flatten = [];
  var subrows;
  $scope.$watch('rows', function(rows){
    var flatten = [];
    angular.forEach(rows, function(row){
      subrows = row.subrows;
      delete row.subrows;
      flatten.push(row);
      if(subrows){
        angular.forEach(subrows, function(subrow){
          flatten.push( angular.extend(subrow, {subrow: true}) );
        });
      }
    });
    $scope.flatten = flatten;
  });

}
HTML:

HTML:


{{row.name}

使用ng repeat无法执行此操作。但是,您可以通过指令来完成

<my-table rows='rows'></my-table>

myApp.directive('myTable',function(){
返回{
限制:'E',
链接:函数(范围、元素、属性){
var html='';
angular.forEach(作用域[attrs.rows],函数(行,索引){
html+=''+row.name+'';
if(第行中的“子窗口”){
angular.forEach(row.subrow,函数(subrow,索引){
html+=''+subrow.name+'';
});
}
});
html+='';
元素。替换为(html)
}
}
});

一年多之后,但找到了一个解决办法,至少有两个级别(父亲->儿子)。
只需重复
t车身

<table>
  <tbody ng-repeat="row in rows">
    <tr>
      <th>{{row.name}}</th>
    </tr>
    <tr ng-repeat="sub in row.subrows">
      <td>{{sub.name}}</td>
    </tr>
  </tbody>
</table>

{{row.name}
{{sub.name}}

据我所知,所有浏览器都支持一个表中的多个
tbody
元素。

我有点惊讶,这么多浏览器支持自定义指令,并创建由$watch更新的代理变量

像这样的问题就是AngularJS过滤器产生的原因

从文档中:

A filter formats the value of an expression for display to the user.
我们并不想操纵数据,只是将其格式化以不同的方式显示。让我们制作一个过滤器,它接收行数组,将其展平,然后返回展平的行

.filter('flattenRows', function(){
return function(rows) {
    var flatten = [];
    angular.forEach(rows, function(row){
      subrows = row.subrows;
      flatten.push(row);
      if(subrows){
        angular.forEach(subrows, function(subrow){
          flatten.push( angular.extend(subrow, {subrow: true}) );
        });
      }
    });
    return flatten;
}
})
现在,我们只需将过滤器添加到ngRepeat:

<table class="table table-striped table-hover table-bordered">
  <thead>
    <tr>
      <th>Rows with filter</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="row in rows | flattenRows">
          <td>{{row.name}}</td>
      </tr>
  </tbody>
</table>

带过滤器的行
{{row.name}
如果需要,您现在可以自由地将表与其他过滤器组合,如搜索

虽然多tbody方法是方便且有效的,但它会打乱任何依赖于子行的顺序或索引的css,例如“条带化”表,并假设您没有以不希望重复的方式设置tbody的样式

这里有一个提示:


编辑:我添加了一个subrow值,并在表中使用它来显示哪些行是subrow,正如您所指出的那样。3年多以后,我一直面临着同样的问题,在写指令之前,我尝试了这个方法,它对我很有效:

<table>
    <tbody>
        <tr ng-repeat-start="row in rows">
            <td>
                {{ row.name }}
            </td>
        </tr>
        <tr ng-repeat-end ng-repeat="subrow in row.subrows">
            <td>
                {{ subrow.name }}
            </td>
        </tr>
    </tbody>
</table>

{{row.name}
{{subrow.name}

以下是一个示例。此代码打印
peopeByCity
数组中所有人的所有姓名

TS:

HTML:


{{person.name}


这是基本情况。我不希望表中有一个表,我希望同一个表中的子视图在彼此下面。在这种情况下,您应该简单地展平
对象,以便所有行定义都在同一个节点下。现在有一种方法可以单独使用ng repeat来实现这一点。首先将数据结构转换为平面数组,然后使用该新数组将该表构造为一个普通循环(与当前答案类似,没有子循环)。例如,此()将数组转换为一个包含4项的新数组(按照正确的顺序,原始的2个和2个子循环)。然后,只需像下面的答案一样循环(因为我对angularjs一无所知),而不需要内部循环。我确信JSFIDLE中的代码可以被增强和/或缩短,但这或多或少只是给您一个想法,然后专门向subrow对象添加一个新属性,以指示它们是subrow。然后在HTML中循环时,检查特定属性是否存在,并根据它执行操作。这是一个非常好的答案。我认为将行的扩展打包成一个添加到tr元素的指令会更具描述性。@schlingel,这似乎不可能:。我不认为我们可以使用link函数将另一个
..
元素放入现有元素(即使用ng repeat的元素)中。没错,after()在这个上下文中似乎没有预期的效果。感谢这个标记,它帮助了我很多!可爱的回答…似乎重申了Angular不能做任何事情!谢谢@MarkRajcokGreat回答!我喜欢这个主意显然这是HTML,甚至。很高兴知道。我喜欢这一切是多么的灵活如果你使用引导表条带化,这可能不会显示你是怎么做的want@joshcss应该适应语义html,而不是相反。但是在这里angular和bootstrap同样擅长滥用dom…这太棒了,它为我节省了很多不必要的代码。这应该是公认的答案。是否可以在
ng repeat start
中嵌套另一个
ng repeat start
?我不知道!我能够使用嵌套的
ng repeat start
s深入表层次结构中的3个级别。肯定应该是答案是的@ThorkilHolm Jacobsen。它很好地解决了我的层次表问题。提示:如果您需要多个嵌套在一起,请使用隐藏的
tr
s来包含
ng repeat end
最简单但致命的解决方案!您还可以访问父
对象的属性。确实有可能有多个嵌套的ng repeat start,您只需拥有相同数量的ng repeat end,AngularJS就不会吐出错误。
<table>
    <tbody>
        <tr ng-repeat-start="row in rows">
            <td>
                {{ row.name }}
            </td>
        </tr>
        <tr ng-repeat-end ng-repeat="subrow in row.subrows">
            <td>
                {{ subrow.name }}
            </td>
        </tr>
    </tbody>
</table>
export class AppComponent {
  peopleByCity = [
    {
      city: 'Miami',
      people: [
        {
          name: 'John', age: 12
        }, {
          name: 'Angel', age: 22
        }
      ]
    }, {
      city: 'Sao Paulo',
      people: [
        {
          name: 'Anderson', age: 35
        }, {
          name: 'Felipe', age: 36
        }
      ]
    }
  ]
}
<div *ngFor="let personsByCity of peopleByCity">
  <div *ngFor="let person of personsByCity.people">
    {{ person.name }}
  </div>
</div>