Reputation: 3366
Edit: Figured it out. I moved all the html in the body of index.html
to app.component.ts
and everything worked fine. Below answer is correct method.
My issue is that I have a ParentComponent which reads from a service, and posts the data to a sidebar. When you click an item in the sidebar it's supposed to post details about that parent in the main section of the page. Since it requires two different templates, I figured the solution is to use a parent-child relationship where the parent is the sidebar and the child is the detail part and I pass the data to the child to display. Does that sound right? Is there a better way to solve this? I've tried various methods but they all seem outdated as it uses directives
which aren't in use any more.
Edit: the other question is not the same because the answer references directives
which were removed in rc6 release of angular2. This question is post-rc6.
Edit 2: Added some code
index.html:
<header>
<div class="content">This is a header</div>
</header>
<div class="container">
<div class="sidebar">
<div class="content">
<parent-items></parent-items>
</div>
</div>
<div class="main-content">
<div class="content">
<my-app>Loading...</my-app>
<child-cmp [id]="selectedItem.id"></child-cmp>
</div>
</div>
<div class="clearfix"></div>
</div>
child-cmp.ts:
@Component({
selector: 'child-cmp',
})
export class ChildComponent {
@Input() set id(n) {
this.getData(n)
}
getData(id: number): void {
console.log('triggered');
};
}
parent.ts:
@Component({
moduleId: module.id,
selector: 'parent-items',
templateUrl: `<ul class="items">
<li *ngFor="let item of items"
(click)="selectedItem = item"
[class.selected]="item === selectedItem">{{item.name}}</li>
</ul>`,
})
export class ItemsComponent implements OnInit {
items: Item[];
selectedItem: Item;
constructor(private itemService: ItemService) {};
getItems(): void {
this.itemService
.getItems()
.then(items => this.items = items);
}
ngOnInit(): void {
this.getItems();
}
}
Upvotes: 1
Views: 1268
Reputation: 40916
Sounds reasonable. Suppose the parent component has a children
array of identifiers
parent template (sidebar)
<div *ngFor="let child of children">
<a (click)="currentChild = child">{{child.name}}</a>
</div>
When a link is clicked, it will set the current child. The main section would display the current child.
parent template (main)
<child-cmp [id]="currentChild.id"></child-cmp>
Use @Input
in child to accept a new child identifier. When an identifier is set, you can populate the child with new data.
child component
/** Get details from server and populate local variables */
getData(id){
this.http.get('/api/children/'+id).map(data => data.json()).subscribe(
data => { this.name = data.name; }
);
}
/** Executed whenever a new id is set */
@Input() set id(n){ this.getData(n) }
Upvotes: 2