2017-04-15 69 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 –