Abel
Abel

Reputation: 2491

use same component for different routes with different output

In my application I like to create a master (CRUD) for physician. I have a physician component for creating, editing and listing. A separate component for viewing it. I would like to URL's like

physician/create

physician/list

physician/edit/3

So I created route with children

const routes: Routes = [
{
  path: 'physician',
  children: [
    { path: 'list', component: PhysicianComponent },
    { path: 'create', component: PhysicianComponent },
    { path: 'update/:id', component: PhysicianComponent },
    { path: 'view/:id', component: PhysicianViewComponent }
  ]
}

For create, update and list I want to use the same component, but different output using some conditions inside the component class

Upvotes: 19

Views: 20075

Answers (4)

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24406

Yes, by using the ActivatedRoute service and by that you check route parameters and router url to check which condition to apply but that is hard to maintain. Imagine, you just change the url or change the parameter name so you need to change that at the component. Another way is to add data property to each route something like a flag and based on that flag you apply specific conditions-

const routes: Routes = [
{
  path: 'physician',
  children: [
    { path: 'list', component: PhysicianComponent, data: { kind: 'list' } },
    { path: 'create', component: PhysicianComponent, data: { kind: 'create' } },
    { path: 'update/:id', component: PhysicianComponent, data: { kind: 'update' } },
    { path: 'view/:id', component: PhysicianViewComponent, date: { kind: 'view' } }
  ]
}

component:

ngOnInit() {
  this.activeRoutedService.data.subscribe(data => {
    switch (data.kind) {
      //....
    }
  });
}

Upvotes: 31

user4676340
user4676340

Reputation:

You can have only one component and handle the operation to do based on the URL, but I think it isn't the best solution.

If I was you, I would create different components for each page, with their own template and their own functions.

If you don't want to do so, you will have to use a lot of conditions in your template, and in your component's logic. For instance :

constructor(private router: Router) {}

get route() { return this.router.url; }

onFormButtonClick() {
  if (this.router.url.endsWith('physician/create')) { /* ... */ }
  else if (this.router.url.includes('physician/edit/')) { /* ... */ }
}

And in your comoponent

<ng-container *ngIf="route.endsWith('physician/create')">...</ng-container>
<ng-container *ngIf="route.includes('physician/edit/')">...</ng-container>

Upvotes: 1

ashfaq.p
ashfaq.p

Reputation: 5469

You can use the ngSwitch

In your controller, decide what is the route

whichView: string;
constructor(private router: Router) {
  if (this.router.url.endsWith('physician/create')) {
    this.whichView = 'create';
  } else if (this.router.url.endsWith('physician/edit')) {
    this.whichView = 'edit'
  } else {
    this.whichView = 'view'
  }
}

In view:

<container-element [ngSwitch]="whichView">
  <some-element *ngSwitchCase="create">...</some-element>
  <some-element *ngSwitchCase="edit">...</some-element>
  <some-other-element *ngSwitchCase="update">...</some-other-element>
  <some-element *ngSwitchDefault>...</some-element>
</container-element>

Upvotes: 4

Joshua Chan
Joshua Chan

Reputation: 1847

You can set route data and get the data in your component to show different output:

{ path: 'list', component: PhysicianComponent, data: { viewOption: 'list' } },
{ path: 'create', component: PhysicianComponent, data: { viewOption: 'create' } },
{ path: 'update/:id', component: PhysicianComponent, data: { viewOption: 'update' } },

In your component, get the data from ActivatedRoute.snapshot.data

constructor(private route: ActivatedRoute) { }

ngOnInit() {
    this.viewOption = this.route.snapshot.data.viewOption;
}

Upvotes: 4

Related Questions