简体   繁体   English

Angular 2-组件无法正确呈现表标签

[英]Angular 2 - Component fails to render table tags properly

I'm looking to dynamically load some data into a table. 我希望将某些数据动态加载到表中。 The data will show up onto the page, but it will not be properly formatted within my HTML table. 数据将显示在页面上,但在我的HTML表中无法正确格式化。 All the text appears on a single line and has no table format whatsoever. 所有文本都显示在一行上,并且没有任何表格格式。 I have a custom component with the following information: 我有一个自定义组件,其中包含以下信息:

HTML 的HTML

  <table class="table table-hover">
    <thead>
      <tr>
        <th>Book Name</th>
        <th>Author Name</th>
      </tr>
    </thead>
    <tbody>
      <app-books *ngFor="let book of booksArray" [book]="book"></app-books>
    </tbody>
  </table>

I have an @input() decorator in a child component called app-books . 我在名为app-books的子组件中有一个@input()装饰器。

app-books typescript file 应用书籍打字稿文件

  @Input() book: {title: string, author: string, cover_img: string};

  constructor() {
  }

app-books html file 应用程式书籍html档案

<tr>
  <td>{{ book.title }}</td>
  <td>{{ book.author }}</td>
</tr>

If you take a look at your markup, you will see that your tr are embedded in app-books tag. 如果看一下标记,您会发现tr嵌入在app-books标签中。 So your markup is invalid. 因此您的标记无效。 See 看到

在此处输入图片说明

To resolve this, I suggest you use [app-book] for your component so that you can assign it as an attribute of the tr element: 要解决此问题,建议您对组件使用[app-book] ,以便可以将其分配为tr元素的属性:

<tr *ngFor="let book of booksArray" [app-book]="book"></tr>

Also, remove <tr> and </tr> from your app-book component markup. 另外,从app-book组件标记中删除<tr></tr> See the Plunker sample that illustrates this. 请参阅说明了这一点的Plunker示例

Edited 已编辑

Angular 4 introduced the NgComponentOutlet directive that could be useful in this scenario. Angular 4引入了NgComponentOutlet指令,该指令在这种情况下很有用。 But, it does not allow passing an Input parameter to the referenced component. 但是,它不允许将Input参数传递给引用的组件。 See the There is no way to access inputs or outputs of Components created by NgComponentOutlet issue. 请参阅“ 无法访问由NgComponentOutlet创建的组件的输入或输出”问题。 But, I've found the ng-dynamic-component package that can do this. 但是,我发现了可以执行此操作的ng-dynamic-component软件包。 So, your code may be: 因此,您的代码可能是:

Parent component: 父组件:

<table class="table table-hover">
    <thead>
        <tr>
            <th>Book Name</th>
            <th>Author Name</th>
        </tr>
    </thead>
    <tbody>
        <ng-template ngFor let-item [ngForOf]="booksArray" let-i="index" [ngForTrackBy]="trackByFn">
            <ng-container [ngComponentOutlet]="AppBook" [ndcDynamicInputs]="{book: item}"></ng-container>
        </ng-template>
    </tbody>
</table>

Row component: 行组件:

@Component({
  selector: 'tr[app-book]',
  template: `
    <td>{{ book?.title }}</td>
    <td>{{ book?.author }}</td>
  `
})
export class AppBook {
  @Input() book: { title: string, author: string, cover_img: string };
}

The tr[app-book] selector is important here. tr[app-book]选择器在这里很重要。 It tells Angular to render a tr element with the app-book attribute. 它告诉Angular使用app-book属性渲染tr元素。 If you specify it as app-book , Angular will render the <app-book> tag, which is invalid markup. 如果将其指定为app-book ,Angular将呈现<app-book>标记,这是无效的标记。 If you specify it as [app-book] , Angular will render <div app-book> , which is also invalid. 如果将其指定为[app-book] ,Angular将呈现<div app-book> ,这也是无效的。 See the sample that illustrates this. 请参阅说明这一点的示例

If you pass the complete booksArray to the child component it not only makes it for a better separation of concerns, but it also allows you manipulate that data at a component level. 如果将完整的booksArray传递给子组件,则不仅可以更好地分离关注点,还可以在组件级别操作该数据。

Try this: 尝试这个:

App.html App.html

<app-books [books]="booksArray"></app-books>

AppBooksComponent.ts AppBooksComponent.ts

export default class AppBooksComponent {
  @Input('booksArray') books: any;
  constructor() {}
}

AppBooksComponent.html AppBooksComponent.html

<tr *ngFor="book in books">
  <td>{{ book.title }}</td>
  <td>{{ book.author }}</td>
</tr>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM