【问题标题】:Angular 2/4 can't read object in initForm()Angular 2/4 无法读取 initForm() 中的对象
【发布时间】:2017-04-06 22:48:57
【问题描述】:

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

如果您查看 console.log 语句,您会发现该对象在 ngOnInit() 函数内工作,但在 initForm() 内不工作。我在这里想念什么?如何让整个组件都可以访问 this.data?

payee-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() 调用的事件之前,它不起作用。我现在明白为什么我现在会出现这种行为,所以谢谢你的链接。我只需要一些关于我的特定用例的帮助

【问题讨论】:

  • 如果我在订阅中调用initForm(),我会在页面加载时收到错误消息,抱怨需要调用initForm()。在我触发触发getPayee() 调用的事件之前,它不起作用。我现在明白为什么我现在会出现这种行为,所以谢谢你的链接。我只需要一些关于我的特定用例的帮助。
  • 确切的错误信息是什么?而且我刚刚注意到您正在使用字符串值... let payeeCompany='this.data.company' 将是字符串文字。您应该使用:let payeeCompany=this.data.company 但您也可以在构建表单 'company': newFormControl(this.data.company) 时分配它。但是告诉我确切的错误信息,让我们看看我是否可以帮忙:)
  • @AJT_82。大声笑是的,这些字符串值是为了使未定义的错误静音,以便我可以进行故障排除。你回家后我会试试你的答案。看起来它会起作用。
  • 确定!让我知道进展如何:)

标签: angular angular2-services angular2-http angular2-observables


【解决方案1】:

第一个问题是调用是异步的,因此在检索数据之前调用initForm。更多信息在这里:How do I return the response from an Observable/http/async call in angular2? 所以你需要在回调中调用方法。

测试了代码,看起来,当您在回调中添加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

【讨论】:

  • 工作就像一个魅力。
  • 太棒了!很高兴听到:)
【解决方案2】:

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

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

【讨论】:

  • 我正在使用响应式表单(数据驱动)。 ng 模型会起作用吗?
  • 在 this.data = data; 之后调用 initForm();
  • @aimprogman。如果我在那里调用它,我会在页面加载时收到关于 initForm() 未被调用的错误。在我触发调用getPayee() 的点击事件后它确实有效,但由于我没有在页面加载时调用initForm(),因此不会加载表单并显示错误。
猜你喜欢
  • 2018-02-11
  • 1970-01-01
  • 2017-03-20
  • 2018-09-02
  • 2017-10-10
  • 1970-01-01
  • 2018-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多