Давайте возьмем образец. У меня есть форма, которая управляет информацию о компании:
<form [ngFormModel]="companyForm">
<field label="Name" [state]="companyForm.controls.name">
<input [ngFormControl]="companyForm.controls.name" [(ngModel)]="company.name"/> {{name.valid}}
</field>
<field label="Tags">
<tags [(labels)]="company.labels"></tags>
</field>
<button type="submit" [disabled]="!companyForm.valid">Submit</button>
</form>
Как вы можете видеть, я использую два вспомогательных компонентов:
- В
field
тот, который стремится построить макет для блока поля с помощью Bootstrap3. Он принимает переменную область для предоставления элемента формы (ввод, выбор, текстовая область). Этот компонент также использует связанный элемент управления для отображения ошибок проверки, если таковые имеются.
tags
тот, который управляет атрибутом tags
, который представляет собой список строк. Он позволяет отображать, добавлять и удалять теги.
Вы можете видеть, что каждый элемент формы использует двустороннюю привязку. Это означает, что каждый элемент формы связан с свойством объекта компонента. Здесь находится company
, который является свойством компонента.
Это означает, что если вы хотите отправить форму, вы можете использовать этот объект company
для создания полезной нагрузки соответствующего HTTP-запроса, например.
Давайте рассмотрим еще несколько вопросов, связанных с объектом company
. Для входов это очевидно с помощью директивы ngModel с этим синтаксисом: [(ngModel)]
. С дополнительным компонентом tags
это, возможно, не так очевидно.
На самом деле вам нужно определить входы и выходы для управления labels
с двумя способами привязок:
@Input labels:string[]
@Output labelsChanged: EventEmitter
Когда метки обновлялись, необходимо вызвать emit
метод labelsChanged
.
Вот полный код TagsComponent
компонента:
@Component({
selector: 'tags',
template: `
<div *ngIf="labels">
<span *ngFor="#label of labels" style="font-size:14px"
class="label label-default" (click)="removeLabel(label)">
{{label}} <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</span>
<span> | </span>
<span style="display:inline-block;">
<input [(ngModel)]="labelToAdd" style="width: 50px; font-size: 14px;" class="custom"/>
<em class="glyphicon glyphicon-ok" aria-hidden="true" (click)="addLabel(labelToAdd)"></em>
</span>
</div>
`
})
export class TagsComponent implements OnInit {
@Input()
labels:string[];
@Output()
labelsChange: EventEmitter;
constructor(private elementRef:ElementRef) {
this.labelsChange = new EventEmitter();
}
removeLabel(label:string) {
var index = this.labels.indexOf(label, 0);
if (index != undefined) {
this.labels.splice(index, 1);
this.labelsChange.emit(this.labels);
}
}
addLabel(label:string) {
this.labels.push(this.labelToAdd);
this.labelsChange.emit(this.labels);
this.labelToAdd = '';
}
}
Надеется, что это помогает, Тьерри
В вашем TagsComponent, как это делает Угловыми знать, что входные этикетки и выход labelsChange является двухстороннее а не просто как отдельный, так и отдельный: ? –
Фактически, при преобразовании, если у вас есть вход с именем' something' и output 'somethingChanged', вы можете использовать синтаксис' [(something)] ', чтобы использовать двустороннюю привязку для этого элемента;) –
И он работает для примитивных типов ;-) –