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

OCD*_*Dev 6 angular-material angular angular-reactive-forms

正如标题所说,我有一个包含多个<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,
        ...
    });
}
Run Code Online (Sandbox Code Playgroud)

}

相关的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>
Run Code Online (Sandbox Code Playgroud)

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

Form value { ... "JobType": "0 - Standard", ... } 
Run Code Online (Sandbox Code Playgroud)

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

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

我究竟做错了什么?

编辑:

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

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

小智 7

Angalural Material 比较:(o1:any, o2:any) => boolean from(AngularMaterial select 的 API 参考)

组件.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);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

组件.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>
Run Code Online (Sandbox Code Playgroud)


Joh*_*ohn 6

一些东西

  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>
Run Code Online (Sandbox Code Playgroud)

与你的问题有些无关,为什么要有这两个createForm()initializeForm()方法?为什么不简单

constructor(private fb: FormBuilder) {

    ...

        // Construct forms
        this.createForm();    
}

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