Angular 2/4 无法读取 initForm() 中的对象

Angular 2/4 can't read object in initForm()

我正在 angular 中创建一个编辑表单,但我对从我的后端服务器返回的对象的生命周期感到困惑。当我在 ngOnInit() 中调用我的服务时,我得到了可用的数据。当我将其分配给实例变量时,它在 initForm() 中未定义,即使我在分配该数据后调用 initForm()

如果您查看 console.log 语句,您会发现该对象在 ngOnInit() 函数中运行,但在 initForm() 中不起作用。我在这里错过了什么?如何让整个组件都可以访问 this.data?

收款人-edit.component.ts:

export class PayeeEditComponent implements OnInit, OnDestroy {
  public payee: Payee;
  id: number;
  payeeEditForm: FormGroup;
  data: Payee;
  subscription: Subscription;

  constructor(private router: Router, private route: ActivatedRoute, private payeeService: PayeeService) { }
  ngOnInit() {
    this.route.params
      .subscribe(
        (params: Params) => {
          this.id = +params['id'];
          this.subscription = this.payeeService.getPayee(this.id).subscribe(
            data => {
              this.data = data;
              console.log(this.data.company); //THIS WORKS
            }
          );
        }
      );
    this.initForm();

  }
  private initForm() {
    console.log(this.data.company); //THIS RETURNS UNDEFINED
    let payeeCompany = 'this.data.company';
    let payeeFirstName =  'this.data.first_name;'
    let payeeLastName = 'this.data.last_name;'
    let payeeNotes = 'this.data.notes;'

    this.payeeEditForm = new FormGroup({
      'company': new FormControl(payeeCompany),
      'first_name': new FormControl(payeeFirstName),
      'last_name': new FormControl(payeeLastName),
      'notes': new FormControl(payeeNotes)
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

payee.service.ts:

  getPayee(id: number) {
    return this.http.get(`http://localhost:3000/payees/${id}`)
    .map(data => data.json());
  }

编辑:
如果我将对 initForm() 的调用放在订阅内,我会在页面加载时收到错误消息,抱怨需要调用 initForm()。在我触发触发 getPayee() 调用的事件之前,它不会起作用。我现在明白为什么我现在有这种行为了,所以谢谢你 link。我只需要一些关于我的特定用例的帮助

你给 subscribe 方法的回调比 initForm 方法执行得晚。因为 http 调用需要 X 时间。

您可以做的是将所有属性绑定到输入中的 ([ngModel])。

第一个问题是调用是异步的,因此 initForm 在检索数据之前被调用。更多信息在这里: 所以你需要在回调中调用方法。

测试了代码,看起来,当你在回调中添加 initForm 时它仍然不起作用,即使 设置表单*ngIf="data"。在完全构建表单之前仍然呈现表单,这会引发错误。

所以我在这里看到了两种可能性。设置一个布尔值,例如 showForm 并且除非 showForm 为真,否则不呈现表单。在构建表单后 检索数据后,将标志 showForm 设置为 true。

其他选项是使用 setValue(或 patchValue),您在检索数据后将数据输入到字段中。这是一个例子:

OnInit 中使用空值构建表单:

this.payeeEditForm = new FormGroup({
  'company': new FormControl()
  'first_name': new FormControl()
  'last_name': new FormControl()
  'notes': new FormControl()
})

并且在回调中检索数据时调用 patchForm

this.subscription = this.payeeService.getPayee(this.id)
   .subscribe(data => {
      this.data = data;
      this.patchForm(); // set the values to the form
   });

和您的 patchForm-方法:

patchForm() {
  this.payeeEditForm.setValue({
    company: this.data.company,
    first_name: this.data.first_name,
    last_name: this.data.last_name,
    notes: this.data.notes
  });
}

这似乎工作正常! :) 如果您愿意,设置布尔标志也可以!

这是一个

Demo