你應該只創建一個實現了ControlValueAccessor
接口的組件,然後將其與選擇元素的ngModel
連接。爲了更好的使用我建議先實現一個抽象類:關於實現價值訪問的樣子和作品可以發現here
import { Provider, forwardRef, Type, OpaqueToken } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
export abstract class AbstractValueAccessor implements ControlValueAccessor {
private _value: any = null;
public onChange = (_) => { };
public onTouched =() => { };
public get value(): any {
return this._value;
}
public set value(v: any) {
if (v !== this._value) {
this._value = v;
this.onChange(v);
}
}
public writeValue(value: any) {
this._value = value;
this.onChange(value);
}
public registerOnChange(fn: (_: any) => void): void {
this.onChange = fn;
}
public registerOnTouched(fn:() => void): void {
this.onTouched = fn;
}
}
export function MakeProvider(type: any) {
return {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => type),
multi: true
};
}
更多信息。有關各種訪問器在角度外觀here中的信息。將其綁定
import { Component, ChangeDetectionStrategy, Input, SimpleChanges, OnChanges } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { AbstractValueAccessor, MakeProvider } from './abstract-value-accessor';
@Component({
selector: 'custom-select',
templateUrl: './custom-select.component.html',
providers: [MakeProvider(CustomSelectComponent)],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CustomSelectComponent extends AbstractValueAccessor implements OnChanges {
private data$$ = new BehaviorSubject<any[]>([]);
@Input()
public dataKey: string;
public data$ = this.data$$.asObservable();
public get hasData$() {
return this.data$.map(data => data.length > 0);
}
constructor(private dataService: MyDataService) {
super();
}
ngOnChanges(changes: SimpleChanges) {
if(changes.dataKey && changes.dataKey.currentValue) {
this.getData(changes.dataKey.currentValue);
}
}
private getData(dataKey: string) {
this.dataService.get(dataKey).take(1).subscribe(data => this.data$$.next(data));
}
}
而在你的組件模板您選擇:
然後用它擴展您的組件
<select [(ngModel)]="value" *ngIf="hasData$ | async">
<option [value]="option.value" *ngFor="let option of data$ | async">{{ option.name }}</option>
</select>
然後你可以用它在任何你想喜歡:
<custom-select dataKey="test"></custom-select>
注意:此代碼未經測試,只提供了一個正確的方向。
感謝男人的快速回復。這是我正在尋找的。還有一個查詢如何從這個自定義控件中獲取選定的項目?我應該訪問您在模板中提到的值屬性嗎? –
要訪問當前選定的值,您可以像往常一樣通過'FormControl'使用'reactive-forms',或者像' custom-select>一樣綁定到'ngModel' '。 –
cyrix
太棒了!並非常感謝你。這對我和任何正在尋找這種問題的人都會很有幫助。我會檢查它並設置爲答案。 –