SelectControlValueAccessor

ControlValueAccessor 用于写入 select 控件的值,并监听 select 控件的变化。该值访问器会被 FormControlDirectiveFormControlNameNgModel 指令使用。

The ControlValueAccessor for writing select control values and listening to select control changes. The value accessor is used by the FormControlDirective, FormControlName, and NgModel directives.

NgModules

选择器

属性

属性说明
value: any
onChange: (_: any) => { }

The registered callback function called when a change event occurs on the input element.

onTouched: () => { }

The registered callback function called when a blur event occurs on the input element.

@Input()
compareWith: (o1: any, o2: any) => boolean
Write-only.

Tracks the option comparison algorithm for tracking identities when checking for changes.

说明

在响应式表单中使用 select 控件

Using select controls in a reactive form

下面的例子演示了如何在响应式表单中使用 select 控件。

The following examples show how to use a select control in a reactive form.

import {Component} from '@angular/core'; import {FormControl, FormGroup} from '@angular/forms'; @Component({ selector: 'example-app', template: ` <form [formGroup]="form"> <select formControlName="state"> <option *ngFor="let state of states" [ngValue]="state"> {{ state.abbrev }} </option> </select> </form> <p>Form value: {{ form.value | json }}</p> <!-- {state: {name: 'New York', abbrev: 'NY'} } --> `, }) export class ReactiveSelectComp { states = [ {name: 'Arizona', abbrev: 'AZ'}, {name: 'California', abbrev: 'CA'}, {name: 'Colorado', abbrev: 'CO'}, {name: 'New York', abbrev: 'NY'}, {name: 'Pennsylvania', abbrev: 'PA'}, ]; form = new FormGroup({ state: new FormControl(this.states[3]), }); }
      
      
  1. import {Component} from '@angular/core';
  2. import {FormControl, FormGroup} from '@angular/forms';
  3.  
  4. @Component({
  5. selector: 'example-app',
  6. template: `
  7. <form [formGroup]="form">
  8. <select formControlName="state">
  9. <option *ngFor="let state of states" [ngValue]="state">
  10. {{ state.abbrev }}
  11. </option>
  12. </select>
  13. </form>
  14. <p>Form value: {{ form.value | json }}</p>
  15. <!-- {state: {name: 'New York', abbrev: 'NY'} } -->
  16. `,
  17. })
  18. export class ReactiveSelectComp {
  19. states = [
  20. {name: 'Arizona', abbrev: 'AZ'},
  21. {name: 'California', abbrev: 'CA'},
  22. {name: 'Colorado', abbrev: 'CO'},
  23. {name: 'New York', abbrev: 'NY'},
  24. {name: 'Pennsylvania', abbrev: 'PA'},
  25. ];
  26.  
  27. form = new FormGroup({
  28. state: new FormControl(this.states[3]),
  29. });
  30. }

在模板驱动表单中使用 select 控件

Using select controls in a template-driven form

要在模板驱动表单中使用 select,只要把 ngModelname 属性加到 <select> 标签上即可。

To use a select in a template-driven form, simply add an ngModel and a name attribute to the main <select> tag.

import {Component} from '@angular/core'; @Component({ selector: 'example-app', template: ` <form #f="ngForm"> <select name="state" ngModel> <option value="" disabled>Choose a state</option> <option *ngFor="let state of states" [ngValue]="state"> {{ state.abbrev }} </option> </select> </form> <p>Form value: {{ f.value | json }}</p> <!-- example value: {state: {name: 'New York', abbrev: 'NY'} } --> `, }) export class SelectControlComp { states = [ {name: 'Arizona', abbrev: 'AZ'}, {name: 'California', abbrev: 'CA'}, {name: 'Colorado', abbrev: 'CO'}, {name: 'New York', abbrev: 'NY'}, {name: 'Pennsylvania', abbrev: 'PA'}, ]; }
      
      
  1. import {Component} from '@angular/core';
  2.  
  3. @Component({
  4. selector: 'example-app',
  5. template: `
  6. <form #f="ngForm">
  7. <select name="state" ngModel>
  8. <option value="" disabled>Choose a state</option>
  9. <option *ngFor="let state of states" [ngValue]="state">
  10. {{ state.abbrev }}
  11. </option>
  12. </select>
  13. </form>
  14. <p>Form value: {{ f.value | json }}</p>
  15. <!-- example value: {state: {name: 'New York', abbrev: 'NY'} } -->
  16. `,
  17. })
  18. export class SelectControlComp {
  19. states = [
  20. {name: 'Arizona', abbrev: 'AZ'},
  21. {name: 'California', abbrev: 'CA'},
  22. {name: 'Colorado', abbrev: 'CO'},
  23. {name: 'New York', abbrev: 'NY'},
  24. {name: 'Pennsylvania', abbrev: 'PA'},
  25. ];
  26. }

自定义 option 的选择结果

Customizing option selection

Angular 使用对象标识作为选项。条目标识可能在其实质性数据没有变化的情况发生变化。比如,如果这些条目是通过 RPC 的方式从服务端取到的,当重新执行 RPC 时,就算数据没有变化,第二个响应也会生成一些具有不同对象标识的对象。

Angular uses object identity to select option. It's possible for the identities of items to change while the data does not. This can happen, for example, if the items are produced from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the second response will produce objects with different identities.

要想自定义默认的选项比较算法,<select> 支持一个名叫 compareWith 的输入。 compareWith 接受一个函数,它具有两个参数:option1option2。 如果指定了 compareWith,则 Angular 会根据该函数的返回值来选取一个选项。

To customize the default option comparison algorithm, <select> supports compareWith input. compareWith takes a function which has two arguments: option1 and option2. If compareWith is given, Angular selects option by the return value of the function.

const selectedCountriesControl = new FormControl();
      
      const selectedCountriesControl = new FormControl();
    
<select [compareWith]="compareFn" [formControl]="selectedCountriesControl"> <option *ngFor="let country of countries" [ngValue]="country"> {{country.name}} </option> </select> compareFn(c1: Country, c2: Country): boolean { return c1 && c2 ? c1.id === c2.id : c1 === c2; }
      
      <select [compareWith]="compareFn"  [formControl]="selectedCountriesControl">
    <option *ngFor="let country of countries" [ngValue]="country">
        {{country.name}}
    </option>
</select>

compareFn(c1: Country, c2: Country): boolean {
    return c1 && c2 ? c1.id === c2.id : c1 === c2;
}
    

注意:我们要监听 change 事件,这是因为 input 事件不会在 Firefox 和 IE 的 select 元素上触发: https://bugzilla.mozilla.org/show_bug.cgi?id=1024350 https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/4660045/

Note: We listen to the 'change' event because 'input' events aren't fired for selects in Firefox and IE: https://bugzilla.mozilla.org/show_bug.cgi?id=1024350 https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/4660045/

方法

Sets the "value" property on the input element. The "selectedIndex" property is also set if an ID is provided on the option element.

writeValue(value: any): void
      
      writeValue(value: any): void
    
参数
value any

The checked value

返回值

void

Registers a function called when the control value changes.

registerOnChange(fn: (value: any) => any): void
      
      registerOnChange(fn: (value: any) => any): void
    
参数
fn (value: any) => any

The callback function

返回值

void

Registers a function called when the control is touched.

registerOnTouched(fn: () => any): void
      
      registerOnTouched(fn: () => any): void
    
参数
fn () => any

The callback function

返回值

void

Sets the "disabled" property on the select input element.

setDisabledState(isDisabled: boolean): void
      
      setDisabledState(isDisabled: boolean): void
    
参数
isDisabled boolean

The disabled value

返回值

void