Angular2表行作为组件


99

我正在实验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>

并且在组件中,模板具有<tr> <td>内容。

但是现在该表不再起作用。这意味着内容不再显示在列中。在浏览器中,检查器向我显示DOM元素如下所示:

    <table>
        <table-line ...>
            <tbody>
                <tr> ....

我该如何工作?

Answers:


110

使用现有的表格元素作为选择器

table元素不允许将<table-line>元素作为子元素,浏览器只会在找到它们时将其删除。您可以将其包装在组件中,并仍然使用允许的<tr>标签。只是"tr"用作选择器。

使用 <template>

<template>也应允许,但并非在所有浏览器中都适用。Angular2实际上从不<template>向DOM 添加元素,而只是在内部对其进行处理,因此,它也可以在所有带有Angular2的浏览器中使用。

属性选择器

另一种方法是使用属性选择器

@Component({
  selector: '[my-tr]',
  ...
})

<tr my-tr>

因此,我将使用选择器='tr'创建我的TableItemComponent。但是如何在其他地方使用“ tr”解决不同的问题呢?
fbenoit '16

6
如果父组件包含您的自定义tr标签,则将使用它,否则将发生默认的浏览器行为。您还可以将属性或类添加到组件选择器,例如<tr line-item>使用组件选择器"tr[line-item] "<tr class="line-item">使用组件选择器tr.line-item。这样,您就可以完全控制。我还没有在Angular2中尝试过任何一种方法,但是我很确定这是可行的。
君特Zöchbauer

5
这有什么真正的缺点吗?它工作正常,但是默认设置tslint直接我的风格指南推荐反对这一点。我不喜欢关闭建议的掉毛规则,但据我所知,这似乎是一个相当随意的样式规则,在某些情况下(例如OP的问题)是不可避免的
Rob

1
我很确定没有缺点,只是元素选择器更常见,因此应为默认设置。如果有一个有效的情况,例如表元素或<li>类似的情况,我看不出为什么不使用它的任何原因。
君特Zöchbauer

2
使我的组件选择器使用tr [line-item]是可行的,并且符合tslint抱怨的Angular Style指南规则STYLE 05-03。
CM

30

我发现该示例非常有用,但是在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(); }
}

1
好答案。我只需要将和添加到中MyTrComponent即可app.module.ts正常工作。
铁托莱瓦

26

这是一个使用带有属性选择器的组件的示例:

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)矮人


是否可以渲染没有根标签的ng组件?Knockout.js中的<!-/ ko->之类的东西。
Ssss


14
这根本不起作用(尝试使用角度2.3)。引发错误:Error: Uncaught (in promise): Error: Template parse errors: Can't bind to 'myTr' since it isn't a known property of 'tr'.
Vukasin

要使其正常工作,您需要在选择器上添加[]。别忘了
6

6

我为组件样式添加了“ display:contents”。

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/


1
如果可能,请尝试提供其他说明,而不只是提供代码。这样的答案往往会更有用,因为它们可以帮助社区成员,尤其是新开发人员更好地了解解决方案的原因,并可以帮助避免需要解决后续问题。
拉詹

嗨@Rajan,谢谢你的提示。我只是发现了contents工作原理,所以我不想基于错误的假设在此放置信息...我理解后添加了解释,但是如果有人注意到它有错误,请随时指出它^ ^。我还添加了一个链接,以便人们可以进行进一步的调查...我注意到一件事,尽管它说这在IE11上不起作用,但我在IE 11.657.18362.0上进行了尝试,并且效果很好(但是,由于我使用角形,某处可能会有一个polyfill,所以我不能保证在其他环境下100%
填充

很好的答案。海事组织这应该被接受。
adamsfamily

-3

试试这个

@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{}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.