ChatGPT解决这个技术问题 Extra ChatGPT

Angular2 表格行作为组件

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

我怎样才能使这项工作?


G
Günter Zöchbauer

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

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

使用 <template>

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

属性选择器

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

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

像这样使用

<tr my-tr>

如果父组件包含您的自定义 tr 标记,它将被使用,否则将发生默认浏览器行为。您还可以将属性或类添加到组件选择器,例如带有组件选择器 "tr[line-item] "<tr line-item> 或带有组件选择器 tr.line-item<tr class="line-item">。这样您就可以完全控制。我自己还没有在 Angular2 中尝试过任何这些,但我很确定这可行。
这有什么真正的缺点吗?它工作正常,但是 tslint 的默认设置将我引导到 style guide 推荐反对。我不喜欢关闭推荐的 linting 规则,但据我所知,这似乎是一个相当随意的风格规则,在某些情况下是不可避免的(例如 OP 的问题)
我很确定没有缺点,除了元素选择器更常见,因此应该是默认值。如果有像表格元素或 <li> 或类似的有效案例,我看不出有什么理由不使用它。
让我的组件选择器使用 tr[line-item] 工作并符合 tslint 抱怨的 Angular 样式指南规则 STYLE 05-03。
这只是一个风格规则。如果使用它是一个错误,他们将完全删除对它的支持,而不是创建样式规则。您的用例正是它实际受支持的原因。只需禁用 linter 规则。
D
DudeOfDoom

我发现该示例非常有用,但它在 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 并且工作正常。
M
Mark Rajcok

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

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


是否可以在没有根标签的情况下呈现 ng 组件?类似于 Knockout.js 中的 的东西。
这根本不起作用(尝试使用 angular 2.3)。抛出的错误:Error: Uncaught (in promise): Error: Template parse errors: Can't bind to 'myTr' since it isn't a known property of 'tr'.
要使其工作,您需要在 Selector 上添加 [ ]。不要忘记这一点。
R
Ruben Negredo

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

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/


如果可能,请努力提供额外的解释,而不仅仅是代码。这样的答案往往更有用,因为它们可以帮助社区成员,尤其是新开发人员更好地理解解决方案的推理,并且可以帮助避免需要解决后续问题。
嗨@Rajan,感谢您的提示。我刚刚发现 contents 是如何工作的,所以我不想根据错误的假设把信息放在那里......我添加了我理解的解释,但如果有人注意到它有错误,请随时指出出来了^^。我还添加了一个链接,以便人们可以进一步调查......我注意到一件事,虽然它说这在 IE11 上不起作用,但我在 IE 11.657.18362.0 上尝试了它并且它运行良好(但是,因为我使用角度,某处可能有一个polyfill,所以我不能保证在其他环境中100%)
M
Matsteel

尝试这个

@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{}

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅