我正在创建一个通用组件(在Angular 5.1.0中)。我们称之为多部分组件。它允许用户上下创建和移动部件(例如就业历史)。我使用这篇文章作为我的首发,它起作用:Angular pass multiple templates to Component
然而,当我将组件放在表单标签中时,我的组件停止工作。我已经在Augery中研究了它,据我所知,数据看起来是正确的。但是,在初始显示中,所有输入字段都显示在数组中的最后一项!一旦我在UI中手动更正,它工作正常,所以它是某种初始显示问题。我把调试绑定放在显示输入字段和非输入字段之间的区别。
这是我的通用多部分组件:
import { Component, TemplateRef, ElementRef, ContentChild, OnInit, Input, ViewChild,AfterViewInit } from '@angular/core';
@Component({
selector: 'vue-multipart',
templateUrl: './vue-multipart.component.html',
styleUrls: ['./vue-multipart.component.css']
})
export class VueMultipartComponent implements OnInit, AfterViewInit {
//@Input()
//@ViewChild('theForm') theForm;
@Input()
private label: string;
@Input() itemsData: any[];
@ContentChild(TemplateRef) itemTemplate: TemplateRef;
constructor() {
}
ngOnInit() {
}
ngAfterViewInit() {
console.log(this.itemsData);
}
getTitleTranslation() {
return this.label;
}
add() {
this.itemsData.push({});
}
remove(index: number) {
this.itemsData.splice(index, 1);
this.markForm();
}
down(index: number) {
var temp = this.itemsData[index + 1];
this.itemsData[index + 1] = this.itemsData[index];
this.itemsData[index] = temp;
this.markForm();
}
up(index: number) {
var temp = this.itemsData[index - 1];
this.itemsData[index - 1] = this.itemsData[index];
this.itemsData[index] = temp;
this.markForm();
}
markForm() {
//this.theForm.form.touched = true;
//this.theForm.form.pristine = false;
}
}
以下是multipart组件的模板:
<span *ngFor="let item of itemsData; let i = index" >
<hr/>
<b>{{i + 1}} {{getTitleTranslation()}}</b>
<span *ngIf="i === 0" >
<button (click)="down(i)">Down</button>
</span>
<span *ngIf="i > 0 && (i < (itemsData.length -1))" >
<button (click)="down(i)">Down</button> <button (click)="up(i)">Up</button>
</span>
<span *ngIf="i > 0 && (i === (itemsData.length -1))" >
<button (click)="up(i)">Up</button>
</span>
<button (click)="remove(i)">Remove</button><br/>
<ng-template
ngFor let-item [ngForOf]="[item]" [ngForTemplate]="itemTemplate">
</ng-template>
</span>
<button (click)="add()">Add</button><br/>
以下是使用上述多部分组件的组件:
import { Component, OnInit, ViewChild } from '@angular/core';
import { Hero } from '../hero';
@Component({
selector: 'app-component-tester',
templateUrl: './component-tester.component.html',
styleUrls: ['./component-tester.component.css']
})
export class ComponentTesterComponent implements OnInit {
@ViewChild('myForm') myForm;
heroes: Hero[] = [];
multipartLabel = "Hero Detail";
isInvalidFormSubmitted: boolean = false;
constructor() {
this.heroes = [
{ id: 11, name: 'Mr. Nice', power: 'Nice Guy' },
{ id: 12, name: 'Narco',power: 'Narco Guy'},
{ id: 13, name: 'Bombasto', power: 'Bombasto Guy' }
];
}
ngOnInit() {
}
}
最后这是组件模板:
<form #myForm="ngForm" novalidate>
<!-- beginning of multipart test -->
<vue-multipart [itemsData]="heroes" [label] = "multipartLabel" >
<ng-template let-item>
{{item.name}}, {{item.power}}
<input #inputElement id="heroName" name="heroName" class="form-control" [(ngModel)]="item.name" placeholder="Name" required #heroName="ngModel">
<input #inputElement id="heroPower" name="heroPower" class="form-control" [(ngModel)]="item.power" placeholder="Hero Power" required #heroPower="ngModel">
</ng-template>
</vue-multipart>
<!-- end of multipart test -->
</form>
当上面的组件有表单标签时,这就是我得到的:
请注意,输入字段外的绑定是正确的,但输入字段始终显示最后一项。在Augury内部,一切看起来都正确,只是UI输入字段没有反映出来。删除表单标记后,它看起来很棒。
答案 0 :(得分:0)
这是因为表单元素具有相同的name
属性。
将其更改为:
[name]="item.name"
和
[name]="item.power"
他们会工作。
以下是工作stackblitz https://angular-vwchuh.stackblitz.io
的链接