ngFormModel上的动态属性?

时间:2016-01-06 11:58:34

标签: typescript angular

我一直在尝试使用ngFormModel和类中的动态属性,没有任何运气。所发生的是第一个值被正确绑定,但是一旦我将变量更改为另一个值,ngFormModel就不会更新以反映这一点。这是一个小型演示,其中包括:

http://plnkr.co/edit/XnbvYtPW9BFDMcdDp0St

export class HeroForm {
  protected ssn: Control;
  protected address: Control;

  build(): ControlGroup
  {
    this.ssn = new Control('', Validators.required);
    this.address = new Control('');

    return new ControlGroup({
        ssn: this.ssn,
        address: this.address
    });
  }
}

在这个演示中,每个Hero都可以拥有一个特定的HeroForm。每个HeroForm都可以包含不同的字段和值,这就是为什么ngFormModel必须是动态的。在我的模板中,我将ngFormModel绑定到当前selectedHero的表单属性。要重现该问题,请选择一个英雄,填写表格并提交。您将在控制台中看到一切正常。但是尝试选择另一个英雄:现在表格总是空的。

此外,同一主题和演示中的另一个问题:我如何拥有基于每个HeroForm类的动态模板?例如,AnotherHeroForm包含与HeroForm不同的字段,那么,我如何为每个字段添加标记?

2 个答案:

答案 0 :(得分:3)

我认为您应该使用ngFormControl而不是ngControl加入HeroDetailComponent类(文件app/hero-detail.component.ts),如下所述:

<form [ngFormModel]="hero.form">
  <p>SSN: <input type="text"
      [ngFormControl]="hero.form.controls.ssn"></p>  <-------
  <p>Address: <input type="text" 
      [ngFormControl]="hero.form.controls.address"></p>  <-------
</form>

以下是重构的plunkr:http://plnkr.co/edit/8eENXoDkcm4vYhZ0XY1H?p=preview

NgFormControl指令允许配置使用组件定义的控件。使用插值(带方括号),您将使用控件参考...

修改

根据你的评论,我更新了我的plunkr以使事情充满活力。

  • 我更新了Hero类以包含我们要更新的字段:

    export class Hero {
      constructor(public id: number, public name: string,
                  public ssn: string, public address: string,
                  public form: ControlGroup) {
        this.form = form.build();
      }
    }
    
  • 我使用相应值创建了Hero的实例:

    var HEROES: Hero[] = [
      new Hero(1, "Narco", 'ssn1', 'address1', new HeroForm()),
      new Hero(2, "Magma", 'ssn2', 'address2', new HeroForm()),
      new Hero(3, "Tornado", 'ssn3', 'address3', new HeroForm()),
    ];
    
  • 我将HeroDetailComponent组件更新为动态,即迭代所提供的英雄的字段:

    @Component({
      selector: 'my-hero-detail',
      template: `
        <div *ngIf="hero">
          <h2>{{hero.name}} details!</h2>
          <div *ngIf="hero">
            <form [ngFormModel]="hero.form">
              <div *ngFor="#elt of hero | fields">
                <p>{{elt}}:
                  <input type="text" [(ngModel)]="hero[elt]" 
                      [ngFormControl]="hero.form.controls[elt]">
                  - Valid: {{hero.form.controls[elt].valid}}
                </p>
              </div>
            </form>
          </div>
        </div>
       `,
       pipes: [FieldsPipe]
     })
     export class HeroDetailComponent {
       @Input()
       public hero: Hero;
     }
    

    ngModelngFormControl都动态绑定到循环中的当前元素(对于特定字段)。我显示相应控件的有效性,以查看是否考虑了更新...

  • 要获取输入的字段列表,我创建了一个自定义管道来获取和过滤它们:

    @Pipe({
      name: 'fields'
    })
    export class FieldsPipe {
      transform(array, args: string): Array<string> {
        // Get fields
        var fields = [];
        for (let elt in array) {
          // Exclude non updatable fields (form, id and name)
          if (elt!=='form' && elt!=='id' && elt!=='name') {
            fields.push(elt);
          }
        }
        return fields;
      }
    }
    

plunkr链接保持不变:http://plnkr.co/edit/8eENXoDkcm4vYhZ0XY1H?p=preview

答案 1 :(得分:0)

您是否尝试过绑定ngModel,就像这个例子一样? https://angular.io/docs/ts/latest/api/common/NgFormModel-directive.html