最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Create table composed by multiple components - Stack Overflow

programmeradmin7浏览0评论

So, as I started to dig in to angular2, I figured I create a table listing persons. One ponent for creating the table (person-list), and one for ponent for each person in the table (person-list-item).

Easy peezy, right? With the below output I realised it was not that easy. As you can see, the table rows are not following the table structure.

By viewing the html in the inspector we can also see that the <person-list-item> is ruining the table.

Is there a way to solve this problem, or should I just create the table rows in the <person-list> element in order to not let the browser ruin the table? I guess this is an issue that applies to other cases where multiple ponents would ruin a certain DOM element.

appponent

import {PersonListComponent} from './person-listponent';
import {Component} from 'angular2/core';

let template=`
<person-list></person-list>
`;

@Component({
    selector:'appz',
    template:template,
    providers:[PersonService],
    directives:[PersonListComponent]
})

export class AppComponent {
    public title;

    constructor(private _personService: PersonService) { 
        this.title=_personService.getPersons();
    }
}

person-listponent

import {Component} from 'angular2/core';
import {PersonListItemComponent} from './person-list-itemponent';
import {Person} from './person';

let template=`
    <h3>Persons</h3>
    <table class="table">
        <thead>
            <tr>
                <th>Firstname</th>
                <th>Lastname</th>
                <th>Age</th>
            </tr>
        </thead>
        <tbody>
            <person-list-item 
                [firstName]="'John'"
                [lastName]="'Doe'"
                [age]='44'>
            </person-list-item>
            <person-list-item 
                [firstName]="'Foo'"
                [lastName]="'Bar'"
                [age]='34'>
            </person-list-item>
        </tbody>
    </table>
`;

@Component({
    selector:'person-list',
    template:template,
    directives:[PersonListItemComponent],
    inputs:['persons']
})
export class PersonListComponent {
    public persons: Person[];
};

person-list-itemponent

import {Component} from 'angular2/core';

let template=`
    <tr>
        <td>{{firstName}}</td>
        <td>{{lastName}}</td>
        <td>{{age}}</td>            
    </tr>
`;

@Component({
    selector:'person-list-item',
    template: template,
    inputs:['firstName', 'lastName', 'age']
})

export class PersonListItemComponent {
    public firstName;
    public lastName;
    public age;
}

So, as I started to dig in to angular2, I figured I create a table listing persons. One ponent for creating the table (person-list), and one for ponent for each person in the table (person-list-item).

Easy peezy, right? With the below output I realised it was not that easy. As you can see, the table rows are not following the table structure.

By viewing the html in the inspector we can also see that the <person-list-item> is ruining the table.

Is there a way to solve this problem, or should I just create the table rows in the <person-list> element in order to not let the browser ruin the table? I guess this is an issue that applies to other cases where multiple ponents would ruin a certain DOM element.

app.ponent

import {PersonListComponent} from './person-list.ponent';
import {Component} from 'angular2/core';

let template=`
<person-list></person-list>
`;

@Component({
    selector:'appz',
    template:template,
    providers:[PersonService],
    directives:[PersonListComponent]
})

export class AppComponent {
    public title;

    constructor(private _personService: PersonService) { 
        this.title=_personService.getPersons();
    }
}

person-list.ponent

import {Component} from 'angular2/core';
import {PersonListItemComponent} from './person-list-item.ponent';
import {Person} from './person';

let template=`
    <h3>Persons</h3>
    <table class="table">
        <thead>
            <tr>
                <th>Firstname</th>
                <th>Lastname</th>
                <th>Age</th>
            </tr>
        </thead>
        <tbody>
            <person-list-item 
                [firstName]="'John'"
                [lastName]="'Doe'"
                [age]='44'>
            </person-list-item>
            <person-list-item 
                [firstName]="'Foo'"
                [lastName]="'Bar'"
                [age]='34'>
            </person-list-item>
        </tbody>
    </table>
`;

@Component({
    selector:'person-list',
    template:template,
    directives:[PersonListItemComponent],
    inputs:['persons']
})
export class PersonListComponent {
    public persons: Person[];
};

person-list-item.ponent

import {Component} from 'angular2/core';

let template=`
    <tr>
        <td>{{firstName}}</td>
        <td>{{lastName}}</td>
        <td>{{age}}</td>            
    </tr>
`;

@Component({
    selector:'person-list-item',
    template: template,
    inputs:['firstName', 'lastName', 'age']
})

export class PersonListItemComponent {
    public firstName;
    public lastName;
    public age;
}
Share Improve this question edited Dec 13, 2017 at 9:24 Oleksii Pavlenko 1,3331 gold badge12 silver badges25 bronze badges asked Jan 6, 2016 at 12:15 cbasscbass 2,5583 gold badges29 silver badges39 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 8

Just use an attribute or class selector instead of the tag selector for your ponent

for example selector: 'tr[person-list-item]' and use it like

<tr person-list-item>

or selector: 'tr[personListItem]' and <tr personListItem>

Alternatively you can use other ways to build a table. For example like shown in https://github./dart-lang/polymer-dart-patterns/blob/b3e8a306d05a9f3aae695a75ca5f4e3dccd64cf5/web/control_flow/using_template_repeat_with_a_table_row/my_element.html for a similar use case for Polymer where CSS is used to set div to behave like a table/tr/td

<style>
  .table {
    display: table;
  }
  .row {
    display: table-row;
  }
  .cell {
    display: table-cell;
  }
</style>
<div class="table">
  <template is="dom-repeat" items="{{fruits}}" as="fruit">
    <div class="row">
      <div class="cell">{{fruit}}</div>
    </div>
  </template>
</div>

Unless PersonListItemComponent will someday be more plicated, I would dispense with that ponent and generate the rows in PersonListComponent using the <template> form of NgFor, which allows for multiple elements to be repeated.

Note: as Günter Zöchbauer mentions in the ments below, some browsers currently do not support <template> elements inside <table> elements. So this approach may be a bit premature.

import {Component, Input} from 'angular2/core';
@Component({
  selector: 'person-list',
  template: `
    <table>
      <tbody>
        <template ngFor #person [ngForOf]="people">
          <tr>
            <td>{{person.name}}
            <td>{{person.age}}
        </template>
      </tbody>
    </table>
  `,
  styles: ['td { border: 1px solid gray } ']
})
export class PersonListComponent {
  @Input() people;
}
@Component({
  selector: 'my-app',
  template: `<person-list [people]="people"></person-list>`,
  directives: [PersonListComponent]
})
export class AppComponent {
  people = [ { name: 'Mark', age: "over 40" }, {name: 'cbass', age: "24?" }];
  constructor() { console.clear(); }
}

plunker

发布评论

评论列表(0)

  1. 暂无评论