Master/Detail Components

Angular has the ability to create a bind relationship between master and detail elements (not to be confused with master/child DB links.  Essentially if an item is selected at the web front, the data corresponding to that element can be injected into another sub component.  Let's see how:

Here is the overall design


Let's look at the component structures:

Master Component

heroes.component.ts
import { Component, OnInit } from '@angular/core';
import {Hero} from '../hero'
import { HEROES } from '../mock-heroes';

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit 
{
  heroes = HEROES;
  selectedHero: Hero;

  constructor() { }

  ngOnInit()
  {
  }

  onSelect(hero : Hero ):void
  {
    this.selectedHero = hero;
  }
}
heroes.component.html
<app-hero-detail [pickedHero]="selectedHero"></app-hero-detail>

<h2>My Heroes</h2>
<ul class="heroes">
  <li *ngFor="let hero of heroes"
      (click)="onSelect(hero)"
      [class.selected]="hero === selectedHero">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

Pay close attention to line 1 - selectedHero matches property at line 13.

Child Component

hero-detail.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { Hero } from '../hero'

@Component({
  selector: 'app-hero-detail',
  templateUrl: './hero-detail.component.html',
  styleUrls: ['./hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit 
{
  @Input()
  pickedHero: Hero;

  constructor() { }

  ngOnInit() {
  }
}

Notice the import of the decorator at line 1, and it's use at line 11.

hero-details.component.html
<div *ngIf="pickedHero">
  <h2>{{pickedHero.nme | uppercase}} Details</h2>
  <div><span>id: </span>{{pickedHero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="pickedHero.name" placeholder="name">
    </label>
  </div>
</div>

Notice the property name pickedHero ties to the property in the class at line 12.

Note

What's really cool about this is the way in the which the two-way bind [property]="other property" works.  If you change something in either parent or child, it is immediately reflected in the counter property.