Search code examples
angularangular-cliangular-componentsangular-cli-v6

Re-using component html in Angular 6


I have the following component template:

<h1>Complexus Vehicle Inventory</h1>

<p *ngIf="!vehicles"><em>No vehicle entries found</em></p>

<div *ngIf="vehicles">
  <form class="form-inline my-2 my-lg-0">
    <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" [(ngModel)]="strMakeOrModel" name="search">
    <button class="btn btn-outline-success my-2 my-sm-0" type="submit" (click)="searchVehicle()">Search</button>
  </form>
</div>


<table class="table" *ngIf="vehicles">
    <thead class="thead-dark">
      <tr>
        <th scope="col">Make</th>
        <th scope="col">Model</th>
        <th scope="col">Engine Capacity</th>
        <th scope="col">Cylinder Variant</th>
        <th scope="col">Top Speed</th>
        <th scope="col">Price (R)</th>
        <th scope="col">Cylinder Capacity</th>
        <th scope="col">Air Pressure/second</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let vehicle of vehicles">
        <td>{{ vehicle.Make }}</td>
        <td>{{ vehicle.Model }}</td>
        <td>{{ vehicle.EngineCapacity }}</td>
        <td>{{ vehicle.CylinderVariant }}</td>
        <td>{{ vehicle.TopSpeed }}</td>
        <td>{{ vehicle.Price }}</td>
        <td>{{ vehicle.IndividualCylinderCapacity }}</td>
        <td>{{ vehicle.AirPressurePerSecond }}</td>
      </tr>
    </tbody>
  </table>

I want to be able to, based on the navigation link clicked in the navigation bar, change the search criteria, that resides in the form. In other words, let's say someone clicked Search by Price, the above component should be updated to incude two text boxes now, serving the price range they would like to search for.

The table layout will stay the same, so this is the re-usable part of the component.

How do you achieve this in Angular 6?


Solution

  • You could specify the search criterion with a route parameter. See this stackblitz for a demo.

    1. Add a search parameter to the component route:
    { path: "vehicles/:search", component: VehiclesComponent }
    
    1. Add the appropriate parameter to each router link:
    <a routerLinkActive="active" routerLink="/vehicles/make">Search: make</a> |
    <a routerLinkActive="active" routerLink="/vehicles/model">Search: model</a> |
    <a routerLinkActive="active" routerLink="/vehicles/price">Search: price</a> |
    
    1. Retrieve the search criterion from the active route:
    import { ActivatedRoute } from '@angular/router';
    import { Subscription } from "rxjs";
    ...
    
    export class VehiclesComponent {
      search: number;
      private subscription: Subscription;
    
      constructor(private route: ActivatedRoute) { }
    
      ngOnInit() {
        this.subscription = this.route.params.subscribe(params => {
          this.search= params["search"];
        });
      }
    
      ngOnDestroy() {
        this.subscription.unsubscribe();
      }
    }
    
    1. Adapt the view to the selected search criterion, for example with an ngSwitch directive:
    <form>
      ...
      <ng-container [ngSwitch]="search">
        <div *ngSwitchCase="'make'">
          <div><input type="radio" name="make">Make 1</div>
          <div><input type="radio" name="make">Make 2</div>
          <div><input type="radio" name="make">Make 3</div>
        </div>
        <div *ngSwitchCase="'model'">
          <select>
            <option>Model 1</option>
            <option>Model 2</option>
            <option>Model 3</option>
          </select>
        </div>
        <div *ngSwitchCase="'price'">
          From: <input type="text">
          To: <input type="text">
        </div>
      </ng-container>
      <button>Search</button>
    </form>
    ...