2017-04-15 14 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); 
    } 
} 

から「コントロール値アクセサ」クラスを持って、私はコンポーネントにそのクラスを拡張:PricingComponentインサイド

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

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

NG_VALUE_ACCESSORのリストにPricingComponentを追加する必要があります。だから、あなたの中にコンポーネントのメタデータが追加:

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 –

関連する問題