angular2 - 可重用组件 - 如何获取选择框的初始值?

时间:2016-06-12 06:47:25

标签: angular

我有一个像这样的问题SO post,但我的可重复使用的选择组件也通过服务从服务器获取数据。

我可以更改事件,使用ngClass等...组件都可以。唯一的问题是,我想得到选择的初始值,不知道如何。

初始值应该是这个对象,并且是我想要得到的:

selectedEnvironment = this.staging; //Intial Value

我可以添加“请选择”以强制进行更改,但我不会做什么

下面是我放置选择器的html

{{selectedEnvironment | json}}
<environment (change)="onChange($event)" [useForm]="false"></environment>

所以{{selectedEnvironment | json}}在加载时为空,但在更改时显示对象。默认属性设置..我只是不知道它是什么。

我尝试使用:

[(ngModel)]="selectedEnvironment"

但是我收到了这个错误:

  

platform-b​​rowser.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>

1 个答案:

答案 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