Angular2表行作为组件

fbe*_*oit 87 angular

我正在尝试使用angular2 2.0.0-beta.0

我有一个表格,行内容由angular2以这种方式生成:

    <table>
        <tr *ngFor="#line of data">
            .... content ....
        </tr>
    </table>
Run Code Online (Sandbox Code Playgroud)

现在这个工作,我想将内容封装到一个组件"table-line".

    <table>
        <table-line *ngFor="#line of data" [data]="line">
        </table-line>
    </table>
Run Code Online (Sandbox Code Playgroud)

在组件中,模板具有<tr> <td>内容.

但是现在桌子不再有用了.这意味着,内容不再显示在列中.在浏览器中,检查器向我显示DOM元素如下所示:

    <table>
        <table-line ...>
            <tbody>
                <tr> ....
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

Gün*_*uer 95

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

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

运用 <template>

<template>也应该被允许但在所有浏览器中都不起作用.Angular2实际上从不<template>向DOM 添加元素,但只在内部处理它们,因此这也可以在Angular2的所有浏览器中使用.

属性选择器

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

@Component({
  selector: '[my-tr]',
  ...
})
Run Code Online (Sandbox Code Playgroud)

用得像

<tr my-tr>
Run Code Online (Sandbox Code Playgroud)

  • 如果父组件包含您的自定义`tr`标记,则将使用它,否则将发生默认的浏览器行为.您还可以使用组件选择器`"tr [line-item]"或`<tr class ="line-item">`向组件选择器添加属性或类,如`<tr line-item>` `tr.line-item`.这样你就可以完全控制.我还没有在Angular2中尝试过这些,但我很确定这是有效的. (6认同)
  • 这有什么真正的缺点吗?它工作正常,但`tslint`的默认设置指向我[样式指南](https://angular.io/docs/ts/latest/guide/style-guide.html#!#05-03)推荐*反对*这个.我不喜欢关闭推荐的linting规则,但据我所知,这似乎是一个相当随意的风格规则,在某些情况下是不可避免的(例如OP的问题) (5认同)
  • 使我的组件选择器使用tr [line-item]是可行的,并且符合tslint抱怨的Angular Style指南规则STYLE 05-03。 (2认同)

小智 27

我发现这个例子非常有用,但它在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(); }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*cok 25

以下是使用带有属性选择器的组件的示例:

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] ];
}
Run Code Online (Sandbox Code Playgroud)

输出:

1   2   3
11  12  13
Run Code Online (Sandbox Code Playgroud)

当然,MyTrComponent中的模板会更复杂,但你明白了.

老(beta.0)plunker.

  • 这根本不起作用(尝试使用角度2.3).抛出错误:```错误:未捕获(在承诺中):错误:模板解析错误:无法绑定到'myTr',因为它不是'tr'的已知属性.`` (12认同)

Rub*_*edo 15

将“显示:内容”添加到组件样式对我来说很有效。

CSS:

.table-line {
    display: contents;
}
Run Code Online (Sandbox Code Playgroud)

HTML:

<table>
    <table-line class="table-line" [data]="line">
    </table-line>
</table>
Run Code Online (Sandbox Code Playgroud)

为什么这有效?

在实例化组件时,angular(编译后)将组件的内容包装在 DOM 中,如下所示:

<table>
    <table-line>
        <tr></tr>
    </table-line>
</table>
Run Code Online (Sandbox Code Playgroud)

但是为了让表格正确显示,tr标签不能被任何东西包裹。

因此,我们将display: contents,添加到这个新元素中。据我了解,这样做是告诉资源管理器不应呈现此标签,并显示内部内容,就好像没有环绕一样。因此,虽然标签仍然存在,但它不会影响表格的视觉效果,并且tr标签被视为标签的直接子代table

如果您想进一步研究内容的工作原理:https : //bitsofco.de/how-display-contents-works/