Reputation: 954
I've been working with Angular for a few months now and started to notice a few patterns with master details where the details is some edit form.
Parent - Child Component Pattern If my details component is a child of the master component I can simple use an Input for the selected object and bind properties and hide show the different components, this pattern seems to work great
Parent - Modal Pattern same as above but usually use one component and just loading the row in a modal
Route Params Pattern If my details is not a child and I use the router, well this only accepts a string so I pass the id and find myself having to make an api call to get the selected object since the route params only support a string and not passing an object. This seems like a use case when maybe the parent doesn't contain all the properties the detail or the form needs.
Shared Service Pattern Using a Service to Share data between the 2 components
Any thoughts or any other patterns I'm missing?
Upvotes: 1
Views: 1078
Reputation: 3206
Depending on your implementation, you can kinda "cache" your data in Service.
@Component({})
export class Component1{
constructor(service: Service, router: Router){}
onSomeAction(id){
this.service.getEntityById(id);
}
redirectToDetails(id: number){
this.router.navigate(["/details", id]);
}
}
@Component({})
export class Component2() implements OnInit{
public entity: Entity;
constructor(service: Service, acivatedRoute: ActivatedRoute){}
ngOnInit(){
this.service.getEntityById(this.activatedRoute.getParams().get("id")).subscribe((entity) => {
this.entity = entity;
});
}
}
@Injectable()
export class Service{
public knownEntities: Map<number, Entity> = new Map<>();
constructor(resource: Resource){
}
getNewEntityById(id: number): Observable<Entity>{
return this.resource.getEntityFromBackendById().map((data) => {
let entity: Entity = data.json();
this.knownEntities.push(id, entity);
return entity;
});
}
getEntityById(id: number): Observable<Entity>{
let knownEntity: Entity = this.knownEntities.get(id);
if(knownEntity){
return Observable.of(knownEntity);
}else{
return this.getNewEntityById(id);
}
}
}
Another approach - to have own RouterParameterService
service which serves as global variable
@Inject()
export class RouterParameterService(){
private _routerParam: any;
public set routerParam(value: any){
this._routerParam = value;
}
public get routerParam(): any{
if(!this._routerParam){
throw Error("No Router param set");
}
let tmp = this._routerParam;
this._routerParam = null;
return tmp;
}
}
@Component({})
export class Component1(){
constructor(service: RouterParameterService, router: Router){}
navigateAction(){
this.service.routerParam = {id: 1, fName: "A", lName = "Tim"};
this.router.navigate("/details");
}
}
@Component({})
export class Component2() implements OnInit{
public entity: any;
constructor(service: RouterParameterService){}
ngOnInit(){
this.entity = this.service.routerParam;
}
}
Upvotes: 1