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>