Wednesday, April 25, 2018

Angular - Interactive Nested Components

Now we want to extend our Display-Only nested component to take input from the user. If the user clicks the stars then notify the parent component.

In the Parent component

Using the nested component

We use it just as you would any component. To get data from the nested component we use the banana in the box [()] syntax.

<myApp-star [rating]='product.starRating' 
      [(notify)]='onRatingClicked($event)'></myApp-star>

$event passes along the appropriate information associated with the event.

Handle the event in the parent component

Add this to the parent component class (.ts file).

  onRatingClicked(message: string) : void {
        // do something with the data sent to us via the message parameter
    }

Implementing the Nested Component

star.component.ts

import { Component, OnChanges, Input } from "@angular/core";
import { Component, OnChanges, Input, Output, EventEmitter } from "@angular/core";

@Component({
    selector: 'pm-star',
    templateUrl: './star.component.html',
    styleUrls: ['./star.component.css']
})
export class StarComponent implements OnChanges {
    @Input() rating: number;

    starWidth: number;

    @Output() ratingClicked: EventEmitter<string> = new EventEmitter<string>();

    ngOnChanges(): void {
        this.starWidth = this.rating * 86/5;
    }

    onClick() : void {
        this.ratingClicked.emit('The rating ' + this.rating + ' was clicked');
    }    

}

Passing data from the nested container to the parent component

The only way to pass data to the parent component is using an event. It needs to be decorated with the @Output for this to work. In this example we are passing a type string, but it could be any object for more complex data. 

star.component.html

<div class="crop" 
    [style.width.px]="starWidth"
    [title]="rating"
    (click)='onClick()'>
    <div style="width: 86px">
        <span class="glyphicon glyphicon-star"></span>
        <span class="glyphicon glyphicon-star"></span>
        <span class="glyphicon glyphicon-star"></span>
        <span class="glyphicon glyphicon-star"></span>
        <span class="glyphicon glyphicon-star"></span>
    </div>
</div>

Notice that rating is a property in the star component and so is title




No comments: