当用于下拉选择时,Formbuilder setvalue()无法按预期工作

时间:2017-10-17 00:36:50

标签: javascript angular angular2-forms

当用于下拉选择时,Angular 2,4 formbuilder setvalue()无法按预期工作。

我有以下下拉列表选项,用Github组织填充:

  <select name="org" formControlName="organizations">
    <option *ngFor="let org of organizations" [ngValue]="org">{{org.organization.login}}</option>
  </select>

这是设置应该选择的Github组织的javascript代码。

  this.pipelineForm = fb.group({
      name:'',
      organizations:'',
      repos: '',
      branches:'',
      runtime:'',
      versions:''
    });

  userService.getOrganizations().subscribe((org:github)=>{
  let organizationName = org.data[0];
   this.organizations = org.data;
      this.projects.subscribe((p)=> {
        p[1].project.subscribe((f)=>{

         this.pipelineForm.get("organizations").setValue(f.organizations, {onlySelf: true});

          //this.pipelineForm.patchValue(f);
        });
      });

    });

我希望在将值传递给setValue()时选择相应的下拉选项。相反,我得到一个空白的选项。我也试过patchValue()。没运气。 enter image description here

3 个答案:

答案 0 :(得分:0)

一个小例子,我们想保存一个数字。见[ngValue] =“org.id”和this.myForm.controls ['organization']。setValue(value);

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
interface Iorganization {
  id: number;
  name: string;
}
@Component({
  selector: 'app-select',
  template: `
  <form [formGroup]="myForm" novalidate>
    <select name="org" formControlName="organization">
      <option *ngFor="let org of organizations" [ngValue]="org.id">{{org.name}}</option>
    </select>
  </form>
  <button (click)="setOrg(1)">Org 1</button>
  <button (click)="setOrg(2)">Org 2</button>
  {{myForm.value |json}}
  `,
  styleUrls: ['./select.component.css']
})
export class SelectComponent implements OnInit {
  organizations: Iorganization[];
  myForm: FormGroup;
  constructor(private fb: FormBuilder) { }
  ngOnInit() {
    this.organizations = [
      { id: 1, name: "org 1" },
      { id: 2, name: "org 2" },
      { id: 3, name: "org 3" },
      { id: 4, name: "org 4" }
    ];
    this.myForm = this.fb.group({
      organization: 1
    })
  }
  setOrg(value: number) {
    this.myForm.controls['organization'].setValue(value);
  }
}

如果我们想保存一个对象-see {{myForm.value | json}} - 我们需要做一些改动。看到我们放了[ngValue] =“org”,但是setOrg()函数使用一个对象来生成setValue。不是,它不是有效的setValue({id:1,name:'org1'})

import { Component, OnInit } from '@angular/core';
....
template: `
<form [formGroup]="myForm" novalidate>
    <select name="org" formControlName="organization">
      <option *ngFor="let org of organizations" [ngValue]="org">{{org.name}}</option>
    </select>
  ....`
export class SelectComponent implements OnInit {
  ...
ngOnInit() {
   this.organizations = [
     { id: 1, name: "org 1" },
        ....
    ];
    this.myForm = this.fb.group({
      organization: null
    })
}
setOrg(value: number) {
   let organization=this.organizations.find(o=>o.id==value);
   this.myForm.controls['organization'].setValue(organization);
}

答案 1 :(得分:0)

我在同一个问题上挣扎,找到了伊戈尔的答案。太模糊了,所以我挖了更多。我终于弄清楚了,尽管缺乏细节,伊戈尔的回答是正确的。希望这将有助于将来其他任何人尝试使setValue()的下拉菜单和对象模型能够一起愉快地工作。

通常,传递给setValue()的对象模型应该与您注入到下拉选择器中的对象相同。例如。如果类型为Organization,则setValue的类型也应为Organization。但是,不必共享完全相同的属性。

要使setValue()patchValue()与对象模型一起工作(与某些原始类型相反),请使用Igor指出的[compareWith]函数。

来自node_modules/@angular/material/select/typings/select.d.ts

  

compareWith是用于将选项值与所选值进行比较的功能。   第一个参数是选项的值。第二个是值   从选择。应该返回一个布尔值。

在您的html模板中,

<select [compareWith]="compareOrgs" name="org" formControlName="organizations">
    <option *ngFor="let org of organizations" [ngValue]="org">{{org.organization.login}}</option>
</select>

然后在您的component.ts文件中定义compareOrgs()函数:

compareOrgs(c1: any, c2: any): boolean {
   return c1 && c2 ? c1.orgId === c2.orgId : c1 === c2; 
}

别忘了调用setValue()函数,例如在ngOnInit()中或在回调函数中(如果它是异步的并且您正在获取数据)。

例如在上面OP的代码的回调中,

// "organization" is whatever object you're trying to patch on the dropdown
this.pipelineForm.get("organizations").setValue(organization)

那么,这就是什么,compareOrgs函数将比较所选值(您将传递给 {{1 }},现在在{{1}中标记为setValue,带有每个 option 值(c2)。具体来说,它将比较所选值和选项值的compareOrgs属性。 c1就是这样,知道在下拉菜单中要预先选择哪个值的。

您现在可以使用orgId访问该对象。

这是对我有帮助的好资源:https://codeburst.io/angular-material-select-module-the-comparewith-function-9dfdb4035373

答案 2 :(得分:-1)

使用compareWith标记上的select属性:

<select ... [compareWith]="compareByName">

然后在组件中实现一个简单的函数

compareByName(org1: Org, org2: Org): boolean {
  return org1 && org2 ? org1.name === org2.name : org1 === org2;
}