【问题标题】:Issue with @Input, ngOnInit() and formGroup@Input、ngOnInit() 和 formGroup 的问题
【发布时间】:2018-07-26 11:30:29
【问题描述】:

我在 Angular (5) 中苦苦挣扎:

我想用一些值初始化一个表单。

为此,我创建了一个组件“group-detail”。

对于这个组件的 html 部分(group-detail.component.html),我有以下内容:

<div *ngIf="group">
  ...
  <!-- Stuff before the form like ({{group.questionGroupId}} -->
  ...
  <form [formGroup]="formGroup" class="group-detail-form">
    <mat-form-field>
      <input matInput placeholder="Group Name" formControlName="groupName" required>
    </mat-form-field>
    <mat-form-field>
      <input matInput placeholder="Creation Date" formControlName="creationDate">
    </mat-form-field>
    <mat-form-field *ngIf="group.lastModificationDate">
      <input matInput placeholder="Last Modification " formControlName="lastModificationDate">
    </mat-form-field>
    <mat-form-field *ngIf="group.isDeleted == true">
      <input matInput placeholder="Deleted" formControlName="isDeleted">
    </mat-form-field>
    <mat-form-field *ngIf="group.deletedOn">
      <input matInput placeholder="Deleton on" formControlname="deletedOn">
    </mat-form-field>
    <mat-form-field>
      <input matInput placeholder="Description" formControlname="description">
    </mat-form-field>
  </form>
  ...
  <!-- Stuff after the form (buttons, ...) -->
  ...
</div>

所以我有一个 formGroup(“formGroup”),其中包含一些带有 formControlName 的输入。

在组件打字稿中,我有以下内容:

export class GroupDetailComponent implements OnInit {

  @Input() group: Group;

  formGroup: FormGroup;

  constructor(
    private route: ActivatedRoute,
    private qgroupService: QGroupService,
    private location: Location
  ) { 
      this.formGroup = new FormGroup({
        groupName: new FormControl({ value: ''}, [Validators.required, Validators.minLength(3)]),
        creationDate: new FormControl({ value: '', disabled: true }),
        lastModificationDate: new FormControl({ value: '', disabled: true }),
        isDeleted: new FormControl({ value: '', disabled: true }),
        deletedOn: new FormControl({ value: '', disabled: true }),
        description: new FormControl({ value: '' })
      });
    }

    ngOnInit() {
      this.getGroup();
      this.formGroup = new FormGroup({
        groupName: new FormControl({ value: this.group.groupName }, [Validators.required, Validators.minLength(3)]),
        creationDate: new FormControl({ value: this.group.creationDate, disabled: true }),
        lastModificationDate: new FormControl({ value: this.group.lastModificationDate, disabled: true }),
        isDeleted: new FormControl({ value: this.group.isDeleted, disabled: true }),
        deletedOn: new FormControl({ value: this.group.deletedOn, disabled: true }),
        description: new FormControl({ value: this.group.description })
      });
    }

    getGroup(): void {
      const id = +this.route.snapshot.paramMap.get('questionGroupId');
      this.qgroupService.getGroup(id).subscribe(group => this.group = group);
    }

}

所以,我必须在构造函数中创建一个新的 formGroup 实例,否则会出错。之后,ngOnInit() 应该获取具有特定 id 的组并使用其中的值重建表单。
我知道 qgroupService 正在返回组,或者至少,当我从方法 qgroupService.getGroup() 登录时,我在 http get 请求之后有组对象。

我还不明白为什么会出现这个错误:

TypeError: 无法读取未定义的属性 'groupName'

因为我认为 getGroup() 会将组返回给

@输入组:组

我可以用它用初始值重新制作我的表单。

也许我把事情复杂化了。

任何建议都将不胜感激(我仍在探索 Angular 5 和 Typescript),

提前谢谢你。

【问题讨论】:

  • 为什么要实例化formGroup 2次?为了让你的代码更简洁,我建议你重构它以使用 FormBuilder 类
  • 您正在创建组的实例两次,这就是您未定义的原因。不需要在构造函数中初始化,只需声明formGroup: FormGroup,然后在ngOnInit中初始化
  • 是的,我肯定不需要两个实例化。问题是,我认为,在 getGroup() 之后我无法访问this.group...所以this.group 仅在订阅函数中定义,并且在订阅完成时,我想 formGroup已经被执行了。但我需要阅读更多关于此的内容。谢谢你们。

标签: angular typescript angular2-forms


【解决方案1】:

我在实现与此非常相似的东西时遇到了一些麻烦。如果我理解正确的话,这里有一些可能会有所帮助的建议:

1) 只设置一次this.formgroup。不要重置它。

2) 在getGroup() 中,遍历this.group 的键以设置每个this.formGroup formControls 的相关值:

getGroup(): void {
  const id = +this.route.snapshot.paramMap.get('questionGroupId');
  this.qgroupService.getGroup(id).subscribe(group => {
      this.group = group;
      for (const key in group) {
           this.formGroup.controls[key].setValue(group[key]);
      }
  });
}

3) 如果组是作为@Input() 传入的,那么getGroup() 是否有必要?如果没有必要,可以在ngOnInit中调用上面的循环:

ngOnInit() {
  for (const key in this.group) {
      this.formGroup.controls[key].setValue(this.group[key]);
  }
}

【讨论】:

  • 嘿,非常感谢,您的解决方案对我有用。我仍然想知道为什么我不能在 ngOnInit() 中的 getGroup() 之后使用 this.group (undefined)。我想我将不得不阅读更多关于 Angular 和 Typescript 的信息。再次感谢您。
  • 乐于助人。至于您剩下的问题,可能是由于与subscribe() 相关的竞争条件。
猜你喜欢
  • 2019-11-27
  • 2021-05-13
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 2019-07-08
相关资源
最近更新 更多