繁体   English   中英

Angular 5 + Angular Material Select + Reactive Forms ==不显示初始选项

[英]Angular 5 + Angular Material Select + Reactive Forms == No initial options displayed

正如标题所说,我有一个反应形式,其中包含多个<mat-select> 在初始表单加载时,即使form.value显示初始选项,也不会显示初始选项。

相关组件:

export class DesJobInfoEditComponent implements OnInit {

...

currentJobData: IJob;
jobTypes: IJobType[];

...

constructor(private fb: FormBuilder) {

    ...

        // Construct forms
        this.createForm();

        this.initializeForm();

}

createForm() {
    this.editJobInfoForm = this.fb.group({
        ...
        JobType: '', // mat-select
        ...
    });
}

initializeForm() {
    this.rebuildForm();
}

rebuildForm() {
    this.editJobInfoForm.reset({
        ...
        JobType: this.jobTypes[this.currentJobData.JobType].DisplayDesc,
        ...
    });
}

}

相关的HTML:

<mat-form-field fxFlex>
      <mat-label>Job Type</mat-label>
       <mat-select formControlName="JobType" placeholder="Job Type">
              <mat-option *ngFor="let jobType of jobTypes" value="jobType.value">
                     {{ jobType.DisplayDesc }}
               </mat-option>
        </mat-select>
  </mat-form-field>

加载表单时,选择不显示最初选择的选项,但是,它们设置正确,显然:

Form value { ... "JobType": "0 - Standard", ... } 

表单上显示的所有内容都是占位符。

这似乎不应该是这么困难。

我究竟做错了什么?

编辑:

加载模块时会加载this.jobTypes ,它是一个存在于我的数据服务中的BehaviorSubject。 我在这个组件的构造函数中订阅它:

this.data.jobTypes.subscribe(jobTypes => { this.jobTypes = jobTypes });

一些东西

  1. [formControlName] 必须[formGroup]一起使用。 如果您不想使用[formControlName] + [formGroup] ,则可以使用[formControl]

  2. 在角度中,将属性指定为value[value]之间存在差异。 当一个属性括在方括号[] ,它被解释为 javascript / angular模板脚本(我认为与{{}}相同)。 当它没有括在括号中时,它被解释为一个字符串(即value="jobType.value" === [value]="'jobType.value'"[value]="jobType.value" === value="{{jobType.value}}" (实际上我认为[value]="jobType.value"value="{{jobType.value}}"之间存在细微差别,但是w / e))。 因此,当您编写<mat-option *ngFor="let jobType of jobTypes" value="jobType.value"> ,每个mat-option的值都是"jobType.value" ,我想,这不是您想要的。 因此,您需要将代码更改为<mat-option *ngFor="let jobType of jobTypes" [value]="jobType.value">

例如

<mat-form-field [formGroup]='editJobInfoForm' fxFlex>
  <mat-label>Job Type</mat-label>
  <mat-select formControlName="JobType" placeholder="Job Type">
    <mat-option *ngFor="let jobType of jobTypes" [value]="jobType.value">
      {{ jobType.DisplayDesc }}
    </mat-option>
  </mat-select>
</mat-form-field>

与您的问题有点无关,为什么同时有createForm()initializeForm()方法? 为什么不简单

constructor(private fb: FormBuilder) {

    ...

        // Construct forms
        this.createForm();    
}

createForm() {
    this.editJobInfoForm = this.fb.group({
        ...
        JobType: this.jobTypes[this.currentJobData.JobType].DisplayDesc,
        ...
    });
}

使用比较功能,因为它...

Step1:显示[compareWith]标签

<mat-form-field>
  <mat-select placeholder="Pick item..." formControlName="selectedItem" 
    [compareWith]="compareFn">
    <mat-option *ngFor="let item of items">
        {{item.name}}
    </mat-option>
  </mat-select>
</mat-form-field>
<button (click)="changeValue()">Change value</button>

第2 compareByValue :声明变量compareFn和函数compareByValue ,如下所示,无需更改

compareFn: ((f1: any, f2: any) => boolean) | null = this.compareByValue;

compareByValue(f1: any, f2: any) { 
  return f1 && f2 && f1.name === f2.name; 
}

嗨,我知道它太晚了,但我知道一个更简单的解决方案。 您的UI(html)组件已正确描述

在您的打字稿中,您将对象与字符串进行比较,而不会产生任何验证。 所以总是将对象与null进行比较(在验证中)

只需在createForm() { this.editJobInfoForm = this.fb.group({ ... JobType: '', // mat-select ... }); } createForm() { this.editJobInfoForm = this.fb.group({ ... JobType: '', // mat-select ... }); }

更改JobType: ''替换为JobType:[null]

Angalural Material compareWith:(o1:any,o2:any)=> boolean from(Angular Material select的API参考)

component.ts

 export class ParentOneComponent implements OnInit {
  materialFormSample: FormGroup;
  constructor() { }

  ngOnInit() {
    this.configureMaterialFormSample();
  }
  name: string = 'Emilius Patrin Mfuruki';
  toppingList: string[] = ['Extra cheese', 'Mushroom', 'Onion', 'Pepperoni', 'Sausage', 'Tomato'];
  selectedToppingList = ['Extra cheese', 'Tomato', 'Onion'];

  compareWithFunc = (a: any, b: any) => a == b;

  configureMaterialFormSample() {
    this.materialFormSample = new FormGroup({
      name: new FormControl(this.name),
      toppings: new FormControl(this.selectedToppingList)
    })
  }
  onSubmitForm() {
    if (this.materialFormSample.valid) {
      console.log('submitting Form Content Valid', this.materialFormSample.value);
    }
  }
}

component.html

<form [formGroup]="materialFormSample" (ngSubmit)="onSubmitForm()" autocomplete="off">
      <mat-form-field class="w-100">
        <input matInput placeholder="Name" formControlName="name">
      </mat-form-field>
      <mat-form-field class="w-100">
        <mat-label>Toppings</mat-label>
        <mat-select formControlName="toppings" multiple [compareWith]="compareWithFunc">
          <mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option>
        </mat-select>
      </mat-form-field>
      <div class="clearfix">
        <button type="submit" mat-raised-button color="primary" class="float-right">Submit Form</button>
      </div>
    </form>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM