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

时间:2018-05-03 19:29:55

标签: angular angular-material angular-reactive-forms

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

Pertinent component.ts:

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 });

4 个答案:

答案 0 :(得分:5)

一些事情

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

  2. 在角度中,将属性指定为value[value]之间存在差异。当一个属性括在括号[]中时,它被解释为 javascript / 角度模板脚本(我认为与{{}}相同)。当括在括号中时,它被解释为一个字符串(即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">

  3. e.g。

    <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,
            ...
        });
    }
    

答案 1 :(得分:0)

直接使用比较功能...

第一步:按所示放置[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:如下所示声明变量compareFn和函数compareByValue,无需更改

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

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

答案 2 :(得分:0)

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

在打字稿中,您正在将对象与字符串进行比较,这不会产生任何验证。 因此,始终将对象与null进行比较(在验证中)

仅在import os import MASH.api as mapi import maya.cmds as cmds class SetMaterial: # create a shader shader = cmds.shadingNode("blinn", asShader=True) # a file texture node file_node = cmds.shadingNode("file", asTexture=True) # a shading group shading_group = cmds.sets(renderable=True, noSurfaceShader=True, empty=True) # connect shader to sg surface shader cmds.connectAttr('%s.outColor' % shader, '%s.surfaceShader' % shading_group) # connect file texture node to shader's color cmds.connectAttr('%s.outColor' % file_node, '%s.color' % shader) class BookGenerator: def __init__(self): self.win=cmds.window('Book Generator', exists=True) if (self.win == 1): cmds.deleteUI('Book Generator', exist=True) self.win = cmds.window(title='Book Generator', widthHeight=(450, 850)) cmds.columnLayout(adj=True, rs=10) cmds.text('!Please select spline!') self.sizeBooks = cmds.intSliderGrp(l="Size of Books", min=0, max=10, field=True) self.thicknessBooks = cmds.intSliderGrp(l="Thickness of Books", min=0, max=10, field=True) self.randomSize = cmds.floatSliderGrp(l="Randomize Size", min=0, max=1, field=True) self.numberOfBooks = cmds.intSliderGrp(l="Number of Books", min=1, max=30, field=True) self.saveLocation = self.create_custom_save_location() cmds.button(label='Create mesh Network', command=self.createMashNetwork) cmds.showWindow(self.win) ####create save location###### def create_custom_save_location(self, path_name='customData'): proj_dir = cmds.internalVar(userWorkspaceDir=True) new_dir = os.path.join(proj_dir, path_name) if not os.path.exists(new_dir): os.makedirs(new_dir) return new_dir def load_fbx(self, *args): self.find_Book = os.path.join(self.saveLocation, 'Book.fbx') cmds.file(self.find_Book, i=True, type='fbx') cmds.select('Line002') #create Mesh Network def createMashNetwork(self, *args): self.loadFbx = self.load_fbx() cmds.select('Line002') # set material self.material = SetMaterial() #self.material.apply_mat_to_object('Line002') numberOfBooks = cmds.intSliderGrp(self.numberOfBooks, q=True, v=True) scaleOfRandomize = cmds.floatSliderGrp(self.randomSize, q=True, v=True) sizeBooks = cmds.intSliderGrp(self.sizeBooks, q=True, v=True) thicknessBooks = cmds.intSliderGrp(self.thicknessBooks, q=True, v=True) self.mashNetwork = mapi.Network() # creating the network self.mashNetwork.createNetwork(name="MASH_Network#") self.mashNetwork.setPointCount(numberOfBooks) # setting the distribution distance to 0 cmds.setAttr(self.mashNetwork.distribute + ".amplitudeX",numberOfBooks*3) # creating the randomNode self.randomNode = self.mashNetwork.addNode("MASH_Random") # changing the initial randomnode attributes cmds.setAttr(self.randomNode.name + ".positionX", 0) cmds.setAttr(self.randomNode.name + ".positionY", 0) cmds.setAttr(self.randomNode.name + ".positionZ", 0) # creating the randomNode self.randomNode = self.mashNetwork.addNode("MASH_Random") # changing the initial randomnode attributes cmds.setAttr(self.randomNode.name + ".scaleY", sizeBooks ) cmds.setAttr(self.randomNode.name + ". scaleX", thicknessBooks) cmds.setAttr(self.randomNode.name + ".randEnvelope", scaleOfRandomize) cmds.setAttr(self.randomNode.name + ".Envelope", 0.2) cmds.select('MASH5_ReproMesh') self.mashNetwork.createCurveWarp(name='Warped') BookGenerator()

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

答案 3 :(得分:0)

Angalural Material compareWith:(o1:any,o2:any)=>布尔值来自(选择Angular Material的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>