【问题标题】:How to pre-populate for data in Angular 2? Using FormGroup?如何在 Angular 2 中预填充数据?使用表单组?
【发布时间】:2017-06-25 14:20:13
【问题描述】:

我正在 Angular 2 中构建一个表单。构建提交表单的过程很简单,但我还需要一个编辑功能。我的问题是我不明白如何从后端预先填充表单中的数据。我确实有后端服务,并且正在从中获取数据。但我不知道这些数据将如何绑定到现有表单。

表单代码如下:-

组件代码

import { Component, OnInit } from '@angular/core';

import { DialogRef, ModalComponent, CloseGuard } from 'angular2-modal';
import { BSModalContext } from 'angular2-modal/plugins/bootstrap';
import { ValidationService } from '../../../shared/core/error-messages/validation-service';

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

export class CustomModalContext extends BSModalContext {
  public num1: number;
  public num2: number;
}

/**
 * A Sample of how simple it is to create a new window, with its own injects.
 */
@Component({
  selector: 'modal-content',
  templateUrl: './custom-modal.component.html'
})
export class CustomModal implements OnInit, CloseGuard, ModalComponent<CustomModalContext> {
  context: CustomModalContext;
  form: FormGroup;

  public wrongAnswer: boolean;

  constructor(public dialog: DialogRef<CustomModalContext>, private fb: FormBuilder) {
    this.context = dialog.context;
    this.wrongAnswer = true;
    dialog.setCloseGuard(this);
  }

  ngOnInit() {
    this.form = this.fb.group({
      'clientName': ['', [Validators.required, ValidationService.isAlphabetNSpace]],
      'hospitalGroup': ['', [Validators.required, ValidationService.isAlphabetNSpace]],
      'addressLineOne': ['', Validators.required],
      'addressLineTwo': ['', Validators.required],
      'city': ['', Validators.required],
      'state': ['', Validators.required],
      'postalCode': ['', Validators.required],
      'deployment': ['', Validators.required],
      'details':this.fb.array([
        this.initDetails()
      ])
    });
  }

  initDetails(){
    return this.fb.group({
          'name':[''],
          'jobTitle':[''],
          'email':[''],
          'systemRole':[''],
          'phoneNumber':['']
        });
  }
  addDetail(){
    const control = <FormArray>this.form.controls['details'];
    control.push(this.initDetails());
  }

  removeDetail(i:number){
    const control = <FormArray>this.form.controls['details'];
    control.removeAt(i);
    console.log(this.form.value)
  }

  onKeyUp(value) {
    this.wrongAnswer = value != 5;
    this.dialog.close();
  }


  beforeDismiss(): boolean {
    return true;
  }

  beforeClose(): boolean {
    return this.wrongAnswer;
  }
}

HTML 代码

<form [formGroup]="form">
            <wizard-container>
                <wizard-section title="Account Information">
                    <div class="row">
                        <div class="col-lg-12">
                            <div class="form-group">
                                <label>Client Name *</label>
                                <input id="clientname" maxlength="100" formControlName="clientName" type="text" class="form-control required">
                                <control-messages [control]="form.controls.clientName"></control-messages>
                            </div>
                            <div class="form-group">
                                <label>Hospital Group *</label>
                                <input id="hospitalgroup" maxlength="100" formControlName="hospitalGroup" type="text" class="form-control required">
                                <control-messages [control]="form.controls.hospitalGroup"></control-messages>
                            </div>
                        </div>
                        <div class="col-lg-6">
                            <div class="form-group">
                                <label>Address</label>
                                <input id="address1" maxlength="60" formControlName="addressLineOne" type="text" class="form-control required">
                                <control-messages [control]="form.controls.addressLineOne"></control-messages>
                            </div>
                        </div>
                        <div class="col-lg-6">
                            <div class="form-group">
                                <label>Address</label>
                                <input id="address2" maxlength="60" formControlName="addressLineTwo" type="text" class="form-control required email">
                                <control-messages [control]="form.controls.addressLineTwo"></control-messages>
                            </div>
                        </div>
                        <div class="col-lg-6">
                            <div class="form-group">
                                <label>City</label>
                                <input id="city" maxlength="100" formControlName="city" type="text" class="form-control required">
                                <control-messages [control]="form.controls.city"></control-messages>
                            </div>
                        </div>
                        <div class="col-lg-6">
                            <div class="row">
                                <div class="col-lg-6">
                                    <div class="form-group">
                                        <label>State</label>
                                        <input id="state" maxlength="20" formControlName="state" type="text" class="form-control required email">
                                        <control-messages [control]="form.controls.state"></control-messages>
                                    </div>
                                </div>
                                <div class="col-lg-6">
                                    <div class="form-group">
                                        <label>Postal Code</label>
                                        <input id="postalcode" maxlength="5" formControlName="postalCode" type="text" class="form-control required email">
                                        <control-messages [control]="form.controls.postalCode"></control-messages>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="col-lg-6">
                            <div class="form-group">
                                <label>Deployment *</label>
                                <input id="deployment" formControlName="deployment" type="text" class="form-control required email">
                                <control-messages [control]="form.controls.deployment"></control-messages>

                            </div>
                        </div>
                    </div>
                </wizard-section>
                <wizard-section title="Module Selection">
                    <p>YYPOYOYOYOYYYOYOY</p>
                </wizard-section>
                <wizard-section title="Create Admin">
                    <div formArrayName="details">
                        <div *ngFor="let detail of form.controls.details.controls; let i=index">
                            <div class="panel-body" [formGroupName]="i">
                                <div class="col-lg-4">
                                    <div class="form-group">
                                        <label>Name *</label>
                                        <input id="name" type="text" formControlName="name" class="form-control" />
                                    </div>
                                </div>
                                <div class="col-lg-4">
                                    <div class="form-group">
                                        <label>Job Title *</label>
                                        <input id="name" type="text" formControlName="jobTitle" class="form-control" />
                                    </div>
                                </div>
                                <div class="col-lg-4">
                                    <div class="form-group">
                                        <label>Email *</label>
                                        <input id="name" type="text" formControlName="email" class="form-control" />
                                    </div>
                                </div>
                                <div class="col-lg-4">
                                    <div class="form-group">
                                        <label>System Role *</label>
                                        <input id="name" type="text" formControlName="systemRole" class="form-control" />
                                    </div>
                                </div>
                                <div class="col-lg-4">
                                    <div class="form-group">
                                        <label>Phone Number *</label>
                                        <input id="name" type="text" formControlName="phoneNumber" class="form-control" />
                                    </div>
                                </div>
                                <div class="col-lg-4">
                                    <div class="form-group">
                                        <button (click)="removeDetail(i)" *ngIf="form.controls.details.controls.length>1">Delete</button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="col-lg-12">
                        <div class="form-group">
                            <button class="btn btn-primary pull-right" (click)="addDetail()">Add Details</button>
                        </div>
                    </div>
                </wizard-section>
            </wizard-container>
        </form>

请帮助我了解如何将表单与后端数据绑定。考虑数据来自服务。(我已经知道如何编写服务,只有数据预填充是一个问题)

【问题讨论】:

    标签: angular angular2-forms


    【解决方案1】:

    要预填充数据,FormGroup 实例有两种方法。设置值和补丁值。在您收到来自服务器的响应后,只需使用这些方法之一设置/修补值

    this.form.patchValue(YOUR_SERVER_RESPONSE);
    

    要了解 setValue() 和 patchValue() 之间的区别,请阅读此处:FormGroup

    【讨论】:

    • 哦,好的。让我检查一次:)
    • 任何关于绑定复选框的cmets?我对拥有它们有点困惑
    • 抱歉,我没有完全理解您的评论。是否要将预定义值绑定到复选框?如果是这样,那么您可以将其绑定到复选框输入的选中属性。 &lt;input type="checkbox" [checked]="isChecked"&gt;
    • 实际上有带有标签的复选框,标签也作为后端服务提供。我不确定如何将复选框值与标签值绑定?
    • 如果您询问服务器响应的另一个问题以及您想对模板中的标签和复选框做什么的详细信息,这将很有帮助。
    【解决方案2】:

    您当前正在构建带有空引号的“表单”。要预填充表单,请将其替换为您要使用的数据。像这样:

    export class CustomModal implements OnInit, CloseGuard, ModalComponent<CustomModalContext> {
      context: CustomModalContext;
      form: FormGroup;
    
      public wrongAnswer: boolean;
    
      constructor(public dialog: DialogRef<CustomModalContext>, private fb: FormBuilder, private clientService: ClientService) {
        this.context = dialog.context;
        this.wrongAnswer = true;
        dialog.setCloseGuard(this);
      }
    
      ngOnInit() {
        let client = this.clientService.getClient();
        this.form = this.fb.group({
          'clientName': [client.clientName, [Validators.required, ValidationService.isAlphabetNSpace]],
          'hospitalGroup': [client.hospitalGroup, [Validators.required, ValidationService.isAlphabetNSpace]],
          'addressLineOne': [client.addressLineOne, Validators.required],
          'addressLineTwo': [client.addressLineTwo, Validators.required],
          'city': [client.city, Validators.required],
          'state': [client.state, Validators.required],
          'postalCode': [client.postalCode, Validators.required],
          'deployment': [client.deployment, Validators.required],
          'details':this.fb.array([
            this.initDetails(client.details)
          ])
        });
      }
    
      initDetails(clientDetails: ClientDetails){
        return this.fb.group({
              'name':[clientDetails.name],
              'jobTitle':[clientDetails.jobTitle],
              'email':[clientDetails.email],
              'systemRole':[clientDetails.systemRole],
              'phoneNumber':[clientDetails.phoneNumber]
            });
      }
      addDetail(){
        const control = <FormArray>this.form.controls['details'];
        control.push(this.initDetails(new ClientDetails()));
      }
    
      removeDetail(i:number){
        const control = <FormArray>this.form.controls['details'];
        control.removeAt(i);
        console.log(this.form.value)
      }
    
      onKeyUp(value) {
        this.wrongAnswer = value != 5;
        this.dialog.close();
      }
    
    
      beforeDismiss(): boolean {
        return true;
      }
    
      beforeClose(): boolean {
        return this.wrongAnswer;
      }
    }
    

    【讨论】:

    • 这可能不起作用,因为在创建视图时 formGroup 必须存在,因此必须作为构造函数的一部分进行初始化。在 ngOnInit 中,使用 setValue 更新 formGroup 的值。
    • 如果在&lt;form&gt;标签中使用*ngIf="form",那么创建视图时formGroup就不必存在了。
    • 啊,很高兴知道,谢谢!我是 Angular 2、TypeSCript 等的新手,并且有一些(很多)令人沮丧的部分......
    • 我有同样的问题,我在 ngOnInit 中有一个 createForm() 方法,用于需要从 firebase 填充的用户配置文件反应式表单,但页面重新加载时表单为空。我知道我会很痛苦。
    猜你喜欢
    • 2017-01-09
    • 2019-10-30
    • 1970-01-01
    • 2021-10-06
    • 2023-02-01
    • 1970-01-01
    • 2018-05-20
    • 2022-01-24
    • 2016-02-06
    相关资源
    最近更新 更多