Angular 2
Direktiv och komponenter: @ Input @ Output
Sök…
Syntax
- Ett sätt som binder från överordnad komponent till en kapslad komponent: [propertyName]
- Envägsbindning från kapslad komponent till moderkomponent: (egenskapens namn)
- Tvåvägsbindande (aka bananbox notation): [(egendom Namn)]
Inmatningsexempel
@input är användbart för att binda data mellan komponenter
Först importera den till din komponent
import { Input } from '@angular/core';
Lägg sedan till ingången som en egenskap i din komponentklass
@Input() car: any;
Låt oss säga att väljaren för din komponent är "bil-komponent", när du ringer till komponenten, lägg till attributet "bil"
<car-component [car]="car"></car-component>
Nu är din bil tillgänglig som ett attribut i ditt objekt (this.car)
Fullständigt exempel:
- 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 och @ Output i en kapslad komponent
Ett knappdirektiv som accepterar en @Input()
att ange en klickgräns tills knappen blir inaktiverad. Den överordnade komponenten kan lyssna på en händelse som kommer att avges när @Output
nås 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);
}
}
}
Föräldrakomponent som använder knappdirektivet och varnar ett meddelande när klickgränsen uppnås:
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 med asynkron data
Ibland måste du hämta data asynkront innan du skickar den till en underordnad komponent för användning. Om barnkomponenten försöker använda informationen innan den har tagits emot kommer det att kasta ett fel. Du kan använda ngOnChanges
att upptäcka förändringar i komponenterna @Input
och vänta tills de definieras innan du agerar på dem.
Föräldrakomponent med asynk samtal till en slutpunkt
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);
}
}
Barnkomponent som har asyncdata som inmatning
Den här underordnade komponenten tar asyncdata som inmatning. Därför måste det vänta på att data finns innan de används. Vi använder ngOnChanges som avfyras varje gång komponentens ingång ändras, kontrollera om uppgifterna finns och använda den om den gör det. Lägg märke till att mallen för barnet inte kommer att visas om en egenskap som förlitar sig på de data som skickas in inte är sann.
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;
}
}