在表单显示问题上使用ng-template

时间:2018-01-03 18:41:03

标签: angular

我正在创建一个通用组件(在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>

当上面的组件有表单标签时,这就是我得到的:

enter image description here

请注意,输入字段外的绑定是正确的,但输入字段始终显示最后一项。在Augury内部,一切看起来都正确,只是UI输入字段没有反映出来。删除表单标记后,它看起来很棒。

enter image description here

1 个答案:

答案 0 :(得分:0)

这是因为表单元素具有相同的name属性。

将其更改为:

[name]="item.name"

[name]="item.power"

他们会工作。

以下是工作stackblitz https://angular-vwchuh.stackblitz.io

的链接