Angular2 - Directive - SelectControlValueAccessor

这个Accessor比之前checkbox的稍微复杂一点点

源码


const SELECT_VALUE_ACCESSOR = CONST_EXPR(new Provider(
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => SelectControlValueAccessor), multi: true}));

/**
* Marks `<option>` as dynamic, so Angular can be notified when options change.
*
* ### Example
*
*
* <select ngControl="city">
* <option *ngFor="#c of cities" [value]="c"></option>
* </select>
*
*/
@Directive({selector: 'option'})
export class NgSelectOption {
}

/**
* The accessor for writing a value and listening to changes on a select element.
*/
@Directive({
selector: 'select[ngControl],select[ngFormControl],select[ngModel]',
host: {'(input)': 'onChange($event.target.value)', '(blur)': 'onTouched()'},
bindings: [SELECT_VALUE_ACCESSOR]
})
export class SelectControlValueAccessor implements ControlValueAccessor {
value: string;
onChange = (_) => {};
onTouched = () => {};

constructor(private _renderer: Renderer, private _elementRef: ElementRef,
@Query(NgSelectOption, {descendants: true}) query: QueryList<NgSelectOption>) {
this._updateValueWhenListOfOptionsChanges(query);
}

writeValue(value: any): void {
this.value = value;
this._renderer.setElementProperty(this._elementRef.nativeElement, 'value', value);
}

registerOnChange(fn: () => any): void { this.onChange = fn; }
registerOnTouched(fn: () => any): void { this.onTouched = fn; }

private _updateValueWhenListOfOptionsChanges(query: QueryList<NgSelectOption>) {
ObservableWrapper.subscribe(query.changes, (_) => this.writeValue(this.value));
}
}
  • 在SelectControlValueAccessor 中注入了NgSelectOption 来处理option change的问题
  • @Query(NgSelectOption, {descendants: true}) query: QueryList<NgSelectOption>) { this._updateValueWhenListOfOptionsChanges(query);

    这里有@Query的用法, 大意是在children里查找NgSelectOption 也就是(option)组件,因为后面 QueryList明确了查找的类型
    并且,可以递归查找,如果option 里嵌套option 也会放到query里。
    在构造里调用了_updateValueWhenListOfOptionsChanges方法

  • ObservableWrapper.subscribe(query.changes, (_) => this.writeValue(this.value));

意思是 当query.changes发生的时候, 执行 后面的writeValue方法,也就是option变化的时候 让select的值更新