【问题标题】:Rendering edit forms in angular2. How can I wait for data from service?在 angular2 中渲染编辑表单。如何等待来自服务的数据?
【发布时间】:2017-05-12 02:07:50
【问题描述】:

我尝试渲染表单以使用来自服务的数据进行编辑,但出现错误,因为我的 initForm() 方法在我从服务获取数据之前调用。我该如何解决?

我的组件

import { Component, OnInit } from '@angular/core';
import { Subscription } from 'rxjs/Rx';
import { ActivatedRoute, Router } from '@angular/router'

import { 
  FormArray, 
  FormControl, 
  Validators, 
  FormGroup,
  FormBuilder
} from '@angular/forms';

import { Company } from './../company';
import { CompanyService } from './../company.service';


@Component({
  selector: 'app-company-edit',
  templateUrl: './company-edit.component.html'
})


export class CompanyEditComponent implements OnInit {
  companyForm: FormGroup;
  private isNew = true;
  private company: Company;
  private companyId: number;
  private subscription: Subscription;

  constructor(private route: ActivatedRoute,
              private companyService: CompanyService,
              private formBuilder: FormBuilder) { }



  ngOnInit() {
    this.subscription = this.route.params.subscribe(
      (params: any) => {
        if (params.hasOwnProperty('id')) {
          this.isNew = false;
          this.companyId = +params['id'];
          this.companyService.getCompany(this.companyId).subscribe((data) => { 
            this.company = data;
            console.log('end sub');
          })

        } else {
          this.isNew = true
          this.company = null;
        }
        this.initForm();
      }
    )
  }

  onSubmit(){

  }

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


  private initForm(){
    let companyName = "";

    if (!this.isNew){
      console.log('start init');
      companyName = this.company.name;
    }

    this.companyForm = this.formBuilder.group({
      name: [companyName, Validators.required]
    })
  }

}

我的服务

import { Injectable } from '@angular/core';
import { Angular2TokenService } from 'angular2-token';
import { Company } from './company';
import { Observable } from 'rxjs/Rx';
import { Headers, Http, Response } from '@angular/http';

import "rxjs/Rx"

@Injectable()
export class CompanyService {
  private company: Company;
  private companies: Company[] = [];

  constructor(private tokenService: Angular2TokenService) { }

  getCompanies(){
    return this.tokenService.get('companies').map((response: Response) => response.json())
  }


  getOwnCompanies(){
    return this.tokenService.get('companies/own').map((response: Response) => response.json())
  }

  getCompany(companyId: number){
    return this.tokenService.get('companies/' + companyId).map((response: Response) => response.json())
  }

}

还有我的表格

<div class="row">
  <div class="col-xs-12">
    <form [formGroup]="companyForm" (ngSubmit)="onSubmit()">
      <div class="row">
        <div class="col-xs-12">
          <button type="submit" class="btn btn-success" [disabled]="!companyForm.valid">Save</button>
          <a class="btn btn-danger" (click)="onCancel()">Cancel</a>
        </div>
      </div>
      <div class="row">
        <div class="col-xs-12">
          <div class="form-group">
            <label for="name">Name</label>
            <input
              type="text"
              id="name"
              class="form-control"
              formControlName="name">
          </div>
        </div>
      </div>
    </form>
  </div>
</div>

我遇到了一个错误

EXCEPTION: Uncaught (in promise): Error: Error in :0:0 caused by: Cannot read property "name" of undefined

TypeError: Cannot read property "name" of undefined at CompanyEditComponent.initForm

因为我不知道如何等待来自服务的数据。我将 console.log 添加到 InitForm 和 ngOnOnit。我在 end sub 之前看到了 start init

【问题讨论】:

    标签: angular observable angular2-template angular2-forms angular2-services


    【解决方案1】:

    获取数据后拨打initForm()即可:

    ngOnInit() {
        this.subscription = this.route.params.subscribe(
          (params: any) => {
            if (params.hasOwnProperty('id')) {
              this.isNew = false;
              this.companyId = +params['id'];
              this.companyService.getCompany(this.companyId).subscribe((data) => { 
                this.company = data;
                this.initForm(); // moved it here
                console.log('end sub');
              })
            } else {
              this.isNew = true
              this.company = null;
            }
          }
        )}
    

    编辑:

    您还需要在表单上使用NgIf 指令,以防止在调用initForm() 之前呈现表单:

    <form *ngIf="companyForm" [formGroup]="companyForm" (ngSubmit)="onSubmit()">
    

    【讨论】:

    • 我试过这个,我得到了下一个错误`EXCEPTION: Uncaught (in promise): Error: Error in ./CompanyEditComponent class CompanyEditComponent - 内联模板:2:10 导致:formGroup 需要一个 FormGroup 实例。请传入一个。示例:
      在您的班级中:this.myGroup = new FormGroup({ firstName: new FormControl() });错误:formGroup 需要一个 FormGroup 实例。请传一个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-01
    • 2017-01-14
    • 2019-05-30
    • 2017-06-19
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多