Angular 2
Директивы и компоненты: @Input @Output
Поиск…
Синтаксис
- Один способ привязки родительского компонента к вложенному компоненту: [propertyName]
- Связывание одного из вложенных компонентов с родительским компонентом: (propertyName)
- Двусторонняя привязка (ака банановая коробка): [(propertyName)]
Пример ввода
@input полезно связывать данные между компонентами
Сначала импортируйте его в свой компонент
import { Input } from '@angular/core';
Затем добавьте ввод как свойство класса компонента
@Input() car: any;
Предположим, что селектор вашего компонента является «автомобильным компонентом», когда вы вызываете компонент, добавляете атрибут «автомобиль»,
<car-component [car]="car"></car-component>
Теперь ваш автомобиль доступен как атрибут вашего объекта (this.car)
Полный пример:
- 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 и @Output в вложенном компоненте
Директива Button, которая принимает @Input()
чтобы указать ограничение на клик, пока кнопка не будет отключена. Родительский компонент может прослушивать событие, которое будет выдаваться, когда ограничение на клик будет достигнуто с помощью @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);
}
}
}
Родительский компонент, который использует директиву Button и предупреждает о том, когда достигнут предел клика:
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 с асинхронными данными
Иногда вам нужно получать данные асинхронно, прежде чем передавать их дочернему компоненту. Если дочерний компонент пытается использовать данные до их получения, он выдаст ошибку. Вы можете использовать ngOnChanges
для обнаружения изменений в компоненте @Input
s и дождаться, пока они не будут определены, прежде чем действовать на них.
Родительский компонент с асинхронным вызовом конечной точки
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);
}
}
Детский компонент, который имеет асинхронные данные как входные данные
Этот дочерний компонент принимает данные async как входные данные. Поэтому он должен дождаться, пока данные будут существовать до его использования. Мы используем ngOnChanges, который срабатывает всякий раз, когда изменяется вход компонента, проверьте, существуют ли данные и используют ли они это, если это произойдет. Обратите внимание, что шаблон для дочернего объекта не будет отображаться, если свойство, которое полагается на передаваемые данные, неверно.
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;
}
}