我有一个像这样的问题SO post,但我的可重复使用的选择组件也通过服务从服务器获取数据。
我可以更改事件,使用ngClass等...组件都可以。唯一的问题是,我想得到选择的初始值,不知道如何。
初始值应该是这个对象,并且是我想要得到的:
selectedEnvironment = this.staging; //Intial Value
我可以添加“请选择”以强制进行更改,但我不会做什么
下面是我放置选择器的html
{{selectedEnvironment | json}}
<environment (change)="onChange($event)" [useForm]="false"></environment>
所以{{selectedEnvironment | json}}在加载时为空,但在更改时显示对象。默认属性设置..我只是不知道它是什么。
我尝试使用:
[(ngModel)]="selectedEnvironment"
但是我收到了这个错误:
platform-browser.umd.js:962 ORIGINAL EXCEPTION:''
没有值访问器
所以从我的构造函数
export class EnvironmentSelectorComponent implements OnInit {
@Input() useForm = false;
isLoading = true;
production: Environment = {
id: '1',
name: 'staging'
};
selectedEnvironment = this.staging;
@Output() change = new EventEmitter();
onChange(newValue:any) {
this.selectedEnvironment = newValue;
this.change.emit({newValue: this.selectedEnvironment})
}
environments = [this.staging];
constructor(private environmentService: EnvironmentService) { }
ngOnInit(){
this.environmentService.getEnvironments()
.subscribe(environments => {
for (var i = 0; environments.length > i; i++)
{ this.environments.push(environments[i])}
},null,() => { this.isLoading = false; });
}
}
以下是组件的HTML:
<select [(ngModel)]="selectedEnvironment" (ngModelChange)="onChange($event)"
[ngClass]="{'form-control': useForm}"
class="custom-select">
<option [ngValue]="i" *ngFor="let i of environments">{{i.name}}</option>
</select>
答案 0 :(得分:2)
正如Günter所提到的,你可以像这样实现ControlValueAccessor
:
import { Component, Input, Output, OnInit, EventEmitter, Provider, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/common';
import { Environment } from './environment';
import { EnvironmentService } from './environment.service';
const SELECTOR_VALUE_ACCESSOR: Provider = new Provider(NG_VALUE_ACCESSOR, {
useExisting: forwardRef(() => EnvironmentSelectorComponent),
multi: true
});
@Component({
selector: 'environment',
providers: [SELECTOR_VALUE_ACCESSOR],
template: `
<select [(ngModel)]="selectedEnvironment" (ngModelChange)="onChange($event)"
[ngClass]="{'form-control': useForm}"
class="custom-select">
<option [ngValue]="i" *ngFor="let i of environments">{{i.name}}</option>
</select>`
})
export class EnvironmentSelectorComponent implements OnInit, ControlValueAccessor {
isLoading = true;
staging: Environment = {
id: '1',
name: 'staging'
};
selectedId: any;
selectedEnvironment: Environment;
@Input() useForm = false;
@Output() ngModelChange = new EventEmitter();
onChange(newValue:any) {
this.ngModelChange.emit(this.selectedEnvironment)
}
environments = [this.staging];
constructor(private environmentService: EnvironmentService) { }
ngOnInit(){
this.environmentService.getEnvironments()
.subscribe(environments => {
for (var i = 0; environments.length > i; i++) {
this.environments.push(environments[i])
}
this.selectedEnvironment = this.environments.find(x => x.id === this.selectedId);
},
null,
() => { this.isLoading = false; });
}
onModelChange: Function = () => {};
onModelTouched: Function = () => {};
writeValue(model: Environment) : void {
if(!model) return;
this.selectedId = model.id;
}
registerOnChange(fn: Function): void {
this.onModelChange = fn;
}
registerOnTouched(fn: Function): void {
this.onModelTouched = fn;
}
}
然后你可以像这样利用它:
<environment [(ngModel)]="selectedEnvironment" [useForm]="false"></environment>
另见plunkr https://plnkr.co/edit/xe824YAYpr2lMxgTvOK4?p=preview