简体   繁体   English

将选择元素绑定到Angular中的对象

[英]Binding select element to object in Angular

I'd like to bind a select element to a list of objects -- which is easy enough:我想将一个选择元素绑定到一个对象列表——这很容易:

@Component({
   selector: 'myApp',
   template: 
      `<h1>My Application</h1>
       <select [(ngModel)]="selectedValue">
          <option *ngFor="#c of countries" value="c.id">{{c.name}}</option>
       </select>`
    })
export class AppComponent{
   countries = [
      {id: 1, name: "United States"},
      {id: 2, name: "Australia"}
      {id: 3, name: "Canada"},
      {id: 4, name: "Brazil"},
      {id: 5, name: "England"}
   ];
   selectedValue = null;
}

In this case, it appears that selectedValue would be a number -- the id of the selected item.在这种情况下, selectedValue似乎是一个数字——所选项目的 id。

However, I'd actually like to bind to the country object itself so that selectedValue is the object rather than just the id.但是,我实际上想绑定到 country 对象本身,以便selectedValue是对象而不仅仅是 id。 I tried changing the value of the option like so:我尝试像这样更改选项的值:

<option *ngFor="#c of countries" value="c">{{c.name}}</option>

but this does not seem to work.但这似乎不起作用。 It seems to place an object in my selectedValue -- but not the object that I'm expecting.它似乎在我的selectedValue中放置了一个对象——但不是我期望的对象。 You can see this in my Plunker example .您可以在我的 Plunker 示例中看到这一点

I also tried binding to the change event so that I could set the object myself based on the selected id;我还尝试绑定到更改事件,以便我可以根据选定的 id 自己设置对象; however, it appears that the change event fires before the bound ngModel is updated -- meaning I don't have access to the newly selected value at that point.但是,似乎 change 事件在绑定的 ngModel 更新之前触发——这意味着我当时无权访问新选择的值。

Is there a clean way to bind a select element to an object with Angular 2?有没有一种干净的方法可以将选择元素绑定到 Angular 2 的对象?

<h1>My Application</h1>
<select [(ngModel)]="selectedValue">
  <option *ngFor="let c of countries" [ngValue]="c">{{c.name}}</option>
</select>

StackBlitz example StackBlitz 示例

NOTE: you can use [ngValue]="c" instead of [ngValue]="c.id" where c is the complete country object.注意:您可以使用[ngValue]="c"而不是[ngValue]="c.id"其中 c 是完整的国家对象。

[value]="..." only supports string values [value]="..."仅支持字符串值
[ngValue]="..." supports any type [ngValue]="..."支持任何类型

update更新

If the value is an object, the preselected instance needs to be identical with one of the values.如果该value是一个对象,则预选实例需要与其中一个值相同。

See also the recently added custom comparison https://github.com/angular/angular/issues/13268 available since 4.0.0-beta.7另请参阅最近添加的自定义比较https://github.com/angular/angular/issues/13268自 4.0.0-beta.7 起可用

<select [compareWith]="compareFn" ...

Take care of if you want to access this within compareFn .如果您想在compareFn中访问this ,请注意。

compareFn = this._compareFn.bind(this);

// or 
// compareFn = (a, b) => this._compareFn(a, b);

_compareFn(a, b) {
   // Handle compare logic (eg check if unique ids are the same)
   return a.id === b.id;
}

This could help:这可能会有所帮助:

<select [(ngModel)]="selectedValue">
  <option *ngFor="#c of countries" [value]="c.id">{{c.name}}</option>
</select>

You can do this too without the need to use [(ngModel)] in your <select> tag您也可以这样做,而无需在<select>标记中使用[(ngModel)]

Declare a variable in your ts file在 ts 文件中声明一个变量

toStr = JSON.stringify;

and in you template do this在你的模板中这样做

 <option *ngFor="let v of values;" [value]="toStr(v)">
      {{v}}
 </option>

and then use然后使用

let value=JSON.parse(event.target.value)

to parse the string back into a valid JavaScript object将字符串解析回有效的 JavaScript 对象

It worked for me:它对我有用:

Template HTML:模板 HTML:

I added (ngModelChange)="selectChange($event)" to my select .我将(ngModelChange)="selectChange($event)"添加到我的select中。

<div>
  <label for="myListOptions">My List Options</label>
  <select (ngModelChange)="selectChange($event)" [(ngModel)]=model.myListOptions.id >
    <option *ngFor="let oneOption of listOptions" [ngValue]="oneOption.id">{{oneOption.name}}</option>
  </select>
</div>

On component.ts:在 component.ts 上:

  listOptions = [
    { id: 0, name: "Perfect" },
    { id: 1, name: "Low" },
    { id: 2, name: "Minor" },
    { id: 3, name: "High" },
  ];

An you need add to component.ts this function:你需要添加到component.ts这个函数:

  selectChange( $event) {
    //In my case $event come with a id value
    this.model.myListOptions = this.listOptions[$event];
  }

Note: I try with [select]="oneOption.id==model.myListOptions.id" and not work.注意:我尝试使用[select]="oneOption.id==model.myListOptions.id"并且不起作用。

============= Another ways can be: ========= ============= 另一种方法可以是:=========

Template HTML:模板 HTML:

I added [compareWith]="compareByOptionId to my select .我将[compareWith]="compareByOptionId到我的select中。

<div>
  <label for="myListOptions">My List Options</label>
  <select [(ngModel)]=model.myListOptions [compareWith]="compareByOptionId">
    <option *ngFor="let oneOption of listOptions" [ngValue]="oneOption">{{oneOption.name}}</option>
  </select>
</div>

On component.ts:在 component.ts 上:

  listOptions = [
    { id: 0, name: "Perfect" },
    { id: 1, name: "Low" },
    { id: 2, name: "Minor" },
    { id: 3, name: "High" },
  ];

An you need add to component.ts this function:你需要添加到component.ts这个函数:

 /* Return true or false if it is the selected */
 compareByOptionId(idFist, idSecond) {
    return idFist && idSecond && idFist.id == idSecond.id;
 }

Just in case someone is looking to do the same using Reactive Forms:以防万一有人希望使用 Reactive Forms 做同样的事情:

<form [formGroup]="form">
  <select formControlName="country">
    <option *ngFor="let country of countries" [ngValue]="country">{{country.name}}</option>
  </select>
  <p>Selected Country: {{country?.name}}</p>
</form>

Check the working example here此处检查工作示例

For me its working like this, you can console event.target.value .对我来说,它是这样工作的,你可以控制台event.target.value

<select (change) = "ChangeValue($event)" (ngModel)="opt">   
    <option *ngFor=" let opt of titleArr" [value]="opt"></option>
</select>

The key is to use a two way binding in the select via [(ngModel)] and use [ngValue] in each option .关键是通过[(ngModel)]select中使用双向绑定,并在每个option中使用[ngValue]

You can even have a default null option and it works with Angular 12.你甚至可以有一个默认的 null 选项,它适用于 Angular 12。

<select name="typeFather" [(ngModel)]="selectedType">
  <option [ngValue]="null">Select a type</option>
  <option *ngFor="let type of types" [ngValue]="type">{{type.title}}</option>
</select>

That approach is always going to work, however if you have a dynamic list, make sure you load it before the model.这种方法总是有效的,但是如果你有一个动态列表,请确保在模型之前加载它。

您可以使用函数选择 ID

<option *ngFor="#c of countries" (change)="onchange(c.id)">{{c.name}}</option>

Create another getter for selected item为所选项目创建另一个吸气剂

<form [formGroup]="countryForm">
  <select formControlName="country">
    <option *ngFor="let c of countries" [value]="c.id">{{c.name}}</option>
  </select>

  <p>Selected Country: {{selectedCountry?.name}}</p>
</form>

In ts :在 ts 中:

get selectedCountry(){
  let countryId = this.countryForm.controls.country.value;
  let selected = this.countries.find(c=> c.id == countryId);
  return selected;
}

此外,如果给定解决方案中的其他任何方法都不起作用,请检查您是否在“AppModule”中导入了“FormsModule”,这对我来说是一个关键。

In app.component.html :app.component.html

<select type="number" [(ngModel)]="selectedLevel">
  <option *ngFor="let level of levels" [ngValue]="level">{{level.name}}</option>
</select>

And app.component.ts :app.component.ts

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  levelNum:number;
  levels:Array<Object> = [
      {num: 0, name: "AA"},
      {num: 1, name: "BB"}
  ];

  toNumber(){
    this.levelNum = +this.levelNum;
    console.log(this.levelNum);
  }

  selectedLevel = this.levels[0];

  selectedLevelCustomCompare = {num: 1, name: "BB"}

  compareFn(a, b) {
    console.log(a, b, a && b && a.num == b.num);
    return a && b && a.num == b.num;
  }
}

You can get selected value also with help of click() by passing the selected value through the function您也可以在 click() 的帮助下通过函数传递选定的值来获取选定的值

<md-select placeholder="Select Categorie"  
    name="Select Categorie" >
  <md-option *ngFor="let list of categ" [value]="list.value" (click)="sub_cat(list.category_id)" >
    {{ list.category }}
  </md-option>
</md-select>

use this way also..也用这个方法。。

<h1>My Application</h1>
<select [(ngModel)]="selectedValue">
     <option *ngFor="let c of countries" value="{{c.id}}">{{c.name}}</option>
 </select>

Attention Angular 2+ users: for some reason, [value] does not work on elements.注意 Angular 2+ 用户:由于某种原因,[value] 不适用于元素。 use [ngModel] instead.改用 [ngModel]。

<select [ngModel]="selectedCountry">
    <option *ngFor="let country of countries" [value]="country">{{country.name}}</option>
</select>

Tested on Angular 11. I need an extra object 'typeSelected'.在 Angular 11 上测试。我需要一个额外的对象“typeSelected”。 Pay attention I'm not using [(ngValue)] as other answers do:请注意,我没有像其他答案那样使用[(ngValue)]

<mat-select formControlName="type" [(value)]="typeSelected" 
            [compareWith]="typeComparation">
  <mat-option *ngFor="let myType of allSurveysTypes" [value]="myType">
    {{myType.title}}
  </mat-option>
</mat-select>
//Declaration.
typeSelected: SurveyType;
...

//Assigning variable 'type' of object 'survey' to 'typeSelected'.
this.typeSelected = survey?.type;
...

    
//Function to compare SurveyType objects.
typeComparation = ( option, value ) =>  {
  if (option && value) {
    return option.id === value.id;
  }
}

This code is very simple:这段代码非常简单:

<select class="form-control" id="marasemaat" [(ngModel)]="fullNamePresentor" 
        [formControl]="stateControl" (change)="onSelect($event.target.value)">
  <option *ngFor="let char of programInfo1;let i = index;" 
          onclick="currentSlide(9,false)" 
          value={{char.id}}>{{char.title + " "}}  ----> {{char.name + " "+ char.family }} ---- > {{(char.time.split('T', 2)[1]).split(':',2)}}</option>
</select>

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

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