Reputation: 1227
I'm playing around with angular 2 (first day;)).
I'm using a component that displays a tr, and the another that will repeat tr's inside of it.
<h3>Sensor list</h3>
<a (click)="refreshSensors()" class="btn btn-primary">Escanear Sensores</a>
<table class="table">
<thead>
<tr>
<th>Sensor</th>
<th>Description</th>
</tr>
</thead>
<sensor-list [sensors]="sensors"></sensor-list>
</table>
and then, in sensor list:
<h3>Sensor list</h3>
<a (click)="refreshSensors()" class="btn btn-primary">Escanear Sensores</a>
<table class="table">
<thead>
<tr>
<th>Sensor</th>
<th>Description</th>
</tr>
</thead>
<sensor-list [sensors]="sensors"></sensor-list>
</table>
While ngFor is repeating the tr's propertly, i'm getting a tag inside my html that makes the table not displaying as it should:
<table class="table">
<thead>
<tr>
<th>Sensor</th>
<th>Description</th>
</tr>
</thead>
<sensor-list><tbody><!--template bindings={}--><tr>
<td>R2D2</td>
<td>Description of r2d2</td>
</tr><tr>
<td>C3PO</td>
<td>Description of c3po</td>
</tr></tbody></sensor-list>
</table>
Do I have to specify the tag i want to display in the component? what is the correct way of doing this in angular?
Upvotes: 1
Views: 5829
Reputation: 21
Do something alike
PARENT COMPONENT TEMPLATE
<tr tool *ngFor='let tool of tools' [_tool]='tool'>
CHILD COMPONENT
import {Component, Input, OnChanges} from '@angular/core'
import {ITool} from '../../app/common/interfaces/ITool'
@Component({
selector: '[tool]',
templateUrl: 'app/toolslist/tool.template.html',
styleUrls: ['app/toolslist/tool.style.css'],
})
export class ToolComponent implements OnChanges{
@Input() _tool: ITool;
constructor() {
}
ngOnChanges():void{
console.log(this._tool);
};
}
Upvotes: 0
Reputation: 6802
I want to expand on that a little bit more. This is tricky one. Probably most of the people starting with dynamically rendered tables encountered that.
Here is the code you've got (cleaned):
import { Component } from '@angular/core';
@Component({
selector: 'table-body',
template: `
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
`
})
class TableBodyComponent {}
@Component({
selector: 'sg-app',
template: `
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<table-body></table-body>
</table>
`,
directives: [TableBodyComponent]
})
export class AppComponent {}
What Angular renders is the following:
And it's not a valid HTML (ref: MDN Table). This way view is broken and unpredictable.
However you still can add components or directives (as an attribute) to the <tr>
tag:
import { Component } from '@angular/core';
@Component({
selector: '[table-row]',
template: `
<td>Cell 1</td>
<td>Cell 2</td>
`
})
class TableBodyComponent {}
@Component({
selector: 'sg-app',
template: `
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr table-row></tr>
</tbody>
</table>
`,
directives: [TableBodyComponent]
})
export class AppComponent {}
This way you can also add *ngFor
to the <tr>
Upvotes: 3
Reputation: 181
Your sensor-list component should be like this
Is your sensor component like this
import {Component, Input} from 'angular2/core';
@Component({
selector: 'sensor-list',
template: `
<tbody>
<tr *ngFor="let row of sensors">
<td>{{row.sensor}}</td>
<td>{{row.description}}</td>
</tr>
<tbody>
`,
providers: []
})
export class Sensor {
@Input('sensors') type: any;
constructor() {}
}
And your home component's template should be like this :
<sensor-list [sensors]="sensors"></sensor-list>
Upvotes: 0
Reputation: 23506
Angular 2 always leaves the host tag in the DOM and only inserts the HTML from your template into this host tag. Since a list of tr
tags isn't really a good use for a component, I would rethink your code design choice there. It would probably be better to put the whole table into a component.
Upvotes: -1