这是一个简单的选择:
<select [(ngModel)]="..." name="..." id="..." required ...>
<option *ngFor="let o of options" [ngValue]="o.value">{{o.label}}</option>
</select>
选项初始化如下:
class MyComponent() {
options;
constructor(someService: MyService) {
this.options = someService.getAllOptions();
}
}
到现在为止还挺好。一切正常。但问题是我需要在不同位置使用完全相同的选项进行选择。所以有很多组件都有这个options
-Property并从我的服务加载它。这是我想避免的大量代码重复。
显然一个组件是一个选项,所以我可以写<mySelect ...>
,但缺点是,我需要通过许多其他变量,如id
,class
,name
,required
和可能更多的属性。所以我更喜欢指令解决方案,所以我可以写<select [(ngModel)]="..." name="..." ... myDirective>
和myDirective
应该根据需要添加选项。我怎样才能做到这一点?
在一个指令中,您可以使用ElementRef
-Parameter轻松访问HTML元素,因此添加元素选项是没有问题的。关键是,您需要使用SelectControlValueAccessor
注册选项。通常,<option>
-Element在编译时被角度识别,并且NgSelectOption
被创建为which registers itself in the constructor。由于您动态创建了该选项元素,因此需要手动执行此步骤:
@Directive({
selector: '[myDirective]'
})
export class MyDirective {
constructor(someService: MyService,
element: ElementRef<HTMLSelectElement>,
renderer: Renderer2,
@Optional() @Host() select: SelectControlValueAccessor) {
someService.getAllOptions().forEach(co => {
const option = document.createElement('option');
option.text = co.displayName;
option.value = co.id;
element.nativeElement.add(option);
new NgSelectOption(new ElementRef(option), renderer, select);
});
}
}