2017-04-15 66 views
0

我有一個「控制值訪問」類從這裏「控制值訪問」 http://blog.rangle.io/angular-2-ngmodel-and-custom-form-components/角2:嵌套元素

export class ValueAccessorBase<T> implements ControlValueAccessor { 
    private innerValue: T; 
    private changed = new Array<(value: T) => void>(); 
    private touched = new Array<() => void>(); 

    get value(): T { 
    return this.innerValue; 
    } 
    set value(value: T) { 
    if (this.innerValue !== value) { 
     this.innerValue = value; 
     this.changed.forEach((f) => f(value)); 
    } 
    } 
    touch() { 
    this.touched.forEach((f) => f()); 
    } 
    writeValue(value: T) { 
    this.innerValue = value; 
    } 
    registerOnChange(fn: (value: T) => void) { 
    this.changed.push(fn); 
    } 
    registerOnTouched(fn:() => void) { 
    this.touched.push(fn); 
    } 
} 

我延伸在一個組件,類:

export class PricingComponent extends ValueAccessorBase<any> implements OnInit { 
    constructor() { 
    super(); // value accessor base 
    } 
} 

內部PricingComponent使用ngModelGroup的模板將多個輸入表單控件分組到一個對象中:

<div ngModelGroup="value"> 
    <md-select [(ngModel)]="value.type" name="type"> 
     <md-option *ngFor="let c of list" [value]="c.code">{{c.dsc}}</md-option> 
    </md-select> 
    <md-input-container> 
     <input [(ngModel)]="value.amount" name="amount" mdInput> 
    </md-input-container> 
    </div> 

而且PricingComponent這樣使用:

<form #form="ngForm"> 
    <app-pricing name="prices" ngModel></app-pricing> 
    {{form.value | json}} 
</form> 

現在,我想從form.value得到的是這樣的:

{ prices: { type: 'high', amount: 542 } } 

但我發現了這個錯誤:

No provider for ControlContainer 

回答

0

您需要將PricingComponent添加到NG_VALUE_ACCESSOR列表中。所以在你組件添加元數據:

providers: [ 
    { 
    provide: NG_VALUE_ACCESSOR, 
    useExisting: forwardRef(() => PricingComponent), 
    multi: true 
    } 
] 
0

不知道這是最好的方式,但我已經沒有擴展ValueAccessorBase類解決它,而是我用ngModelGroup

使用定價組件:

<app-pricing ngModelGroup="multiCurrency"></app-pricing> 

定價組件類:

export class PricingComponent implements OnInit, AfterViewChecked { 
    @ContentChild(NgModelGroup) 
    private _group: NgModelGroup; 

    @ViewChild('pricingType') 
    private _type: NgModel; 

    @ViewChild('pricingAmount') 
    private _amount: NgModel; 

    private _registered = false; 

    ngAfterViewChecked() { 
    if (!this._registered && this._group.control != null) { 
     this._group.control.registerControl('type', this._type.control); 
     this._group.control.registerControl('amount', this._amount.control); 
     this._registered = true; 
    } 
    } 
} 

定價組件模板:

<div> 
    <md-select #pricingType="ngModel" name="type"> 
     <md-option></md-option> 
    </md-select> 
    <md-input-container> 
     <input #pricingAmount="ngModel" name="amount" mdInput> 
    </md-input-container> 
    </div> 

來源:http://plnkr.co/edit/xJr1ZZBkSz3TuT43Tpwm?p=preview

+0

這工作簡單。我還實施了它來解決與此問題無關的另一個問題:https://github.com/angular/angular/issues/9600#issuecomment-339298977 –