Angular 2
Richtlijnen & componenten: @Input @Output
Zoeken…
Syntaxis
- Unidirectionele binding van bovenliggend component naar geneste component: [propertyName]
- Eenzijdige binding van geneste component naar bovenliggende component: (propertyName)
- Tweerichtingsbinding (aka notering bananendoos): [(propertyName)]
Invoervoorbeeld
@input is handig om gegevens tussen componenten te binden
Importeer het eerst in uw component
import { Input } from '@angular/core';
Voeg vervolgens de invoer toe als eigenschap van uw componentklasse
@Input() car: any;
Laten we zeggen dat de selector van uw component 'auto-component' is. Wanneer u de component aanroept, voegt u het kenmerk 'auto' toe
<car-component [car]="car"></car-component>
Nu is uw auto toegankelijk als een kenmerk in uw object (this.car)
Volledig voorbeeld:
- car.entity.ts
export class CarEntity {
constructor(public brand : string, public color : string) {
}
}
- car.component.ts
import { Component, Input } from '@angular/core';
import {CarEntity} from "./car.entity";
@Component({
selector: 'car-component',
template: require('./templates/car.html'),
})
export class CarComponent {
@Input() car: CarEntity;
constructor() {
console.log('gros');
}
}
- garage.component.ts
import { Component } from '@angular/core';
import {CarEntity} from "./car.entity";
import {CarComponent} from "./car.component";
@Component({
selector: 'garage',
template: require('./templates/garage.html'),
directives: [CarComponent]
})
export class GarageComponent {
public cars : Array<CarEntity>;
constructor() {
var carOne : CarEntity = new CarEntity('renault', 'blue');
var carTwo : CarEntity = new CarEntity('fiat', 'green');
var carThree : CarEntity = new CarEntity('citroen', 'yellow');
this.cars = [carOne, carTwo, carThree];
}
}
- garage.html
<div *ngFor="let car of cars">
<car-component [car]="car"></car-component>
</div>
- car.html
<div>
<span>{{ car.brand }}</span> |
<span>{{ car.color }}</span>
</div>
Angular2 @Input en @Output in een geneste component
Een @Input()
die een @Input()
accepteert om een @Input()
te geven totdat de knop wordt uitgeschakeld. De bovenliggende component kan luisteren naar een gebeurtenis die wordt uitgezonden wanneer de @Output
wordt bereikt via @Output
:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'limited-button',
template: `<button (click)="onClick()"
[disabled]="disabled">
<ng-content></ng-content>
</button>`,
directives: []
})
export class LimitedButton {
@Input() clickLimit: number;
@Output() limitReached: EventEmitter<number> = new EventEmitter();
disabled: boolean = false;
private clickCount: number = 0;
onClick() {
this.clickCount++;
if (this.clickCount === this.clickLimit) {
this.disabled = true;
this.limitReached.emit(this.clickCount);
}
}
}
Bovenliggend onderdeel dat de knoprichtlijn gebruikt en een bericht waarschuwt wanneer de kliklimiet is bereikt:
import { Component } from '@angular/core';
import { LimitedButton } from './limited-button.component';
@Component({
selector: 'my-parent-component',
template: `<limited-button [clickLimit]="2"
(limitReached)="onLimitReached($event)">
You can only click me twice
</limited-button>`,
directives: [LimitedButton]
})
export class MyParentComponent {
onLimitReached(clickCount: number) {
alert('Button disabled after ' + clickCount + ' clicks.');
}
}
Angular2 @ Input met asynchrone gegevens
Soms moet u gegevens asynchroon ophalen voordat u deze doorgeeft aan een onderliggende component om te gebruiken. Als de onderliggende component probeert de gegevens te gebruiken voordat deze zijn ontvangen, geeft dit een foutmelding. U kunt ngOnChanges
gebruiken om veranderingen in de @Input
een component te detecteren en wachten tot ze zijn gedefinieerd voordat u erop @Input
.
Bovenliggend onderdeel met asynchrone aanroep naar een eindpunt
import { Component, OnChanges, OnInit } from '@angular/core';
import { Http, Response } from '@angular/http';
import { ChildComponent } from './child.component';
@Component ({
selector : 'parent-component',
template : `
<child-component [data]="asyncData"></child-component>
`
})
export class ParentComponent {
asyncData : any;
constructor(
private _http : Http
){}
ngOnInit () {
this._http.get('some.url')
.map(this.extractData)
.subscribe(this.handleData)
.catch(this.handleError);
}
extractData (res:Response) {
let body = res.json();
return body.data || { };
}
handleData (data:any) {
this.asyncData = data;
}
handleError (error:any) {
console.error(error);
}
}
Onderliggende component die asynchrone gegevens als invoer heeft
Deze onderliggende component neemt de asynchrone gegevens als invoer. Daarom moet het wachten tot de gegevens bestaan voordat het wordt gebruikt. We gebruiken ngOnChanges die wordt geactiveerd wanneer de invoer van een component verandert, controleren of de gegevens bestaan en gebruiken deze als dit het geval is. Merk op dat de sjabloon voor het kind niet zal tonen of een eigenschap die afhankelijk is van de doorgegeven gegevens niet waar is.
import { Component, OnChanges, Input } from '@angular/core';
@Component ({
selector : 'child-component',
template : `
<p *ngIf="doesDataExist">Hello child</p>
`
})
export class ChildComponent {
doesDataExist: boolean = false;
@Input('data') data : any;
// Runs whenever component @Inputs change
ngOnChanges () {
// Check if the data exists before using it
if (this.data) {
this.useData(data);
{
}
// contrived example to assign data to reliesOnData
useData (data) {
this.doesDataExist = true;
}
}