Reputation: 1712
I have list component which list Group item as table. One of the link is allow user to edit item. Edit item is separate component. When user click on edit, i need to pass existing data to edit component. How can i do that?
Here is my list component
<div class='table-responsive'>
<table class='table' *ngIf='groups && groups.length'>
<thead>
<tr>
<th>Avatar Image</th>
<th>Display Name</th>
<th>Description</th>
<th>Member Count</th>
<th>Total Post</th>
<th>Last Modify Date</th>
<th></th>
</tr>
</thead>
<tr *ngFor='let group of groups | groupFilter:listFilter'>
<td><img [src]='group.group_avatar_image' class="img-responsive" style="max-height: 50px;"></td>
<td><a [href]='group.url'>{{group.display_name}}</a></td>
<td>{{group.description}}</td>
<td>{{group.total_members_count}}</td>
<td>{{group.total_posts}}</td>
<td>{{group.updated_at | date: 'dd/MM/yyyy'}}</td>
<td><a href="#" [routerLink]="['/Edit Group']">Edit</a></td>
</tr>
</table>
</div>
Here is my list component
import { Component, OnInit,Input } from '@angular/core';
import { Group } from '../groupModel';
import { GroupsService } from '../groups.service';
@Component ({
selector: 'groups-lst',
moduleId: module.id,
templateUrl: 'groups-list.component.html'
//styleUrls: ['groups.component.css']
})
export class GroupsList implements OnInit{
constructor(private _groupsService: GroupsService) {}
title: string = 'Groups List';
listFilter: string = '';
errorMessage: string;
groups: Group[];
ngOnInit():void{
this._groupsService.getGroups()
.subscribe (group => this.groups = group,
error => this.errorMessage = <any>error);
}
}
Upvotes: 0
Views: 1734
Reputation: 121
There is one important thing about your approach to mention. It seems like you are thinking about a way to pass an instance of your model to the router. This is not possible by design (for sure, there are ways around like using a service as intermediary, but don't recommend that).
You should think about, that your records displayed within the grid might (and should) have identifiers, like an ordinary id
property. The most common practice is to pass that identifier as parameter to the route and fetch the entity from source again.
Grid component:
<tr *ngFor='let group of groups | groupFilter:listFilter'>
<td><img [src]='group.group_avatar_image' class="img-responsive" style="max-height: 50px;"></td>
<td><a [href]='group.url'>{{group.display_name}}</a></td>
<td>{{group.description}}</td>
<td>{{group.total_members_count}}</td>
<td>{{group.total_posts}}</td>
<td>{{group.updated_at | date: 'dd/MM/yyyy'}}</td>
<td><a href="#" [routerLink]="['/Edit', group.id]">Edit</a></td>
</tr>
In your "edit component" you can use the passed parameter to fetch your group entity:
private route$ : Subscription;
constructor(private route : ActivatedRoute) {}
ngOnInit() {
this.route$ = this.route.params.subscribe(
(params : Params) => {
let id = params["id"];
// fetch the group entity from service / store
});
}
And for sure you need to configure your route to recognize the id
parameter:
export const routes = [
...
{ path : 'Edit/:id', component : ...},
...
];
Upvotes: 4
Reputation: 4888
If components are not related by hierarchy (other than being in the same app) a service allowing subscription to a Subject is the way I usually go.
If components are easily related by hierarchy (parent/child), you can use Outputs.
Note that the service can be used for everything. However, I typically find myself using both.
There is a TON of documentation, and piles of samples, on both (some of which I've written right here on SO). The info you need is definitely available in a variety of questions. I'd be surprised if this question didn't get a dupe flag.
Here is a very bare-bones example of a Subject service, which you inject into any component that needs to "hear" a notification:
const Notes = {
SOME_NAMED_EVENT : 'some_named_event',
... (more named events)
};
class Note {
constructor ( name = '', data = {} ) {
this.name = name;
this.data = data;
}
}
// Example of a subscription/notification style service,
// as opposed to a service that just calls a callback
class NotifierService {
constructor() {
let Rx = require ( 'rxjs' );
this.subject = new Rx.Subject ( );
}
subscribe ( callback ) {
return this.subject.subscribe ( b => callback ( b ) );
}
sendNote ( note ) {
this.subject.next ( note );
}
}
export { NotifierService, Notes, Note }
Upvotes: 0