我正在试验 angular2 2.0.0-beta.0
我有一个表格,并且行内容是由 angular2 这样生成的:
<table>
<tr *ngFor="#line of data">
.... content ....
</tr>
</table>
现在这可行,我想将内容封装到组件“表格行”中。
<table>
<table-line *ngFor="#line of data" [data]="line">
</table-line>
</table>
在组件中,模板具有
但现在这张桌子不再工作了。这意味着,内容不再显示在列中。在浏览器中,检查器显示 DOM 元素如下所示:
<table>
<table-line ...>
<tbody>
<tr> ....
我怎样才能使这项工作?
使用现有的表格元素作为选择器
表格元素不允许 <table-line>
元素作为子元素,浏览器只会在找到它们时将其删除。您可以将其包装在一个组件中并仍然使用允许的 <tr>
标记。只需使用 "tr"
作为选择器。
使用 <template>
<template>
也应该被允许,但还不能在所有浏览器中工作。 Angular2 实际上从不向 DOM 添加 <template>
元素,而只是在内部处理它们,因此这也可以在所有带有 Angular2 的浏览器中使用。
属性选择器
另一种方法是使用属性选择器
@Component({
selector: '[my-tr]',
...
})
像这样使用
<tr my-tr>
我发现该示例非常有用,但它在 2,2.3 版本中不起作用,因此经过多次挠头后,它通过一些小改动使其再次起作用。
import {Component, Input} from '@angular/core'
@Component({
selector: "[my-tr]",
template: `<td *ngFor='let item of row'>{{item}}</td>`
})
export class MyTrComponent {
@Input("line") row:any;
}
@Component({
selector: "my-app",
template: `<h1>{{title}}</h1>
<table>
<tr *ngFor="let line of data" my-tr [line]="line"></tr>
</table>`
})
export class AppComponent {
title = "Angular 2 - tr attribute selector!";
data = [ [1,2,3], [11, 12, 13] ];
constructor() { console.clear(); }
}
MyTrComponent
添加到 app.module.ts
并且工作正常。
这是一个使用带有属性选择器的组件的示例:
import {Component, Input} from '@angular/core';
@Component({
selector: '[myTr]',
template: `<td *ngFor="let item of row">{{item}}</td>`
})
export class MyTrComponent {
@Input('myTr') row;
}
@Component({
selector: 'my-app',
template: `{{title}}
<table>
<tr *ngFor="let line of data" [myTr]="line"></tr>
</table>
`
})
export class AppComponent {
title = "Angular 2 - tr attribute selector";
data = [ [1,2,3], [11, 12, 13] ];
}
输出:
1 2 3
11 12 13
当然,MyTrComponent 中的模板会涉及更多,但你明白了。
旧 (beta.0) plunker。
Error: Uncaught (in promise): Error: Template parse errors: Can't bind to 'myTr' since it isn't a known property of 'tr'.
在组件样式中添加“显示:内容”对我来说很有效。
CSS:
.table-line {
display: contents;
}
HTML:
<table>
<table-line class="table-line" [data]="line">
</table-line>
</table>
为什么这行得通?
实例化组件时,angular(编译后)将组件的内容包装在 DOM 中,如下所示:
<table>
<table-line>
<tr></tr>
</table-line>
</table>
但是为了让表格正确显示,tr
标记不能被任何东西包裹。
因此,我们将 display: contents
添加到这个新元素。据我了解,这样做是告诉资源管理器不应呈现此标签,并显示内部内容,就好像没有环绕一样。因此,虽然标记仍然存在,但它不会影响表格的视觉效果,并且 tr
标记被视为 table
标记的直接子级。
如果您想进一步了解内容的工作原理:https://bitsofco.de/how-display-contents-works/
contents
是如何工作的,所以我不想根据错误的假设把信息放在那里......我添加了我理解的解释,但如果有人注意到它有错误,请随时指出出来了^^。我还添加了一个链接,以便人们可以进一步调查......我注意到一件事,虽然它说这在 IE11 上不起作用,但我在 IE 11.657.18362.0 上尝试了它并且它运行良好(但是,因为我使用角度,某处可能有一个polyfill,所以我不能保证在其他环境中100%)
尝试这个
@Component({
selecctor: 'parent-selector',
template: '<table><body><tra></tra></body></table>'
styles: 'tra{ display:table-row; box-sizing:inherit; }'
})
export class ParentComponent{
}
@Component({
selecctor: 'parent-selector',
template: '<td>Name</td>Date<td></td><td>Stackoverflow</td>'
})
export class ChildComponent{}
tr
标记,它将被使用,否则将发生默认浏览器行为。您还可以将属性或类添加到组件选择器,例如带有组件选择器"tr[line-item] "
的<tr line-item>
或带有组件选择器tr.line-item
的<tr class="line-item">
。这样您就可以完全控制。我自己还没有在 Angular2 中尝试过任何这些,但我很确定这可行。tslint
的默认设置将我引导到 style guide 推荐反对。我不喜欢关闭推荐的 linting 规则,但据我所知,这似乎是一个相当随意的风格规则,在某些情况下是不可避免的(例如 OP 的问题)<li>
或类似的有效案例,我看不出有什么理由不使用它。