2016-07-06 23 views
4

ドロップダウンメニューからデータをバインドしようとしています。ngModelです。アプリが読み込まれたときにエラーが発生して、それは意味があります。PrimeNGドロップダウンで選択したアイテムのデータバインド

browser_adapter.js:84 EXCEPTION: No value accessor for '' 

これは、エラーがngModelが最初にどのようなデータアプリケーションの負荷にバインドされていないという事実に起因していることを信じるように私をリード。

Observablesを使用するのがベストではありません...ご注意ください。

<p-dropdown [options]="actionsToTake" (onChange)="onToggleCreateActionInput()" 
    [(ngModel)]="action"></p-dropdown> 

HTMLドロップダウンの部分的な関連活字体(除外輸入)

export class ActionView { 
    public actionsToTake: SelectItem[] = []; 
    public action: Action = new Action(); 

    constructor (private actionCreateService: ActionCreateService) { 
    // populate dropdown list (actionsToTake) with data from service call 
    this.actionCreateService.getActionFields().subscribe((resp) => { 
     for (let i = 0; i < resp.data.data.actionElm.length; i++) { 
     this.actionsToTake.push({label: resp.data.data.actionElm[i].name, 
      value: resp.data.data.actionElm[i].name}); 
     } 
    }); 
    } 

    public onToggleCreateActionInput = (action): void => { 
    // test if something in "action" exists, and then do something based on that 
    }; 
} 

ので、アプリが最初にロードしたときに、actionは空です。私はngModelにバインドされた空の値は、アプリケーションを破ることはないと思うが、多分私はエラーを誤解している。最終的には、選択したアイテムをバインドする必要があります。このエラーが発生すると、その時点で私はそのポイントになります。

+0

使用している角度ルータとフォームのバージョンはどれですか? –

+0

ルータ3.0.0-beta.1とフォーム0.2.0 – BrianRT

答えて

1

それは私が非推奨角度の形と新しい角度のフォームを使用しての中間のどこかにいたが判明しました。

import {NgForm, FORM_DIRECTIVES, CORE_DIRECTIVES} from '@angular/common'; 

import {disableDeprecatedForms, provideForms} from '@angular/forms'; 

bootstrap(App, [ 
    disableDeprecatedForms(), 
    provideForms() 
]); 

その後、私は、フォームをインスタンス化し、私の親コンポーネントで、私はからの輸入を変更する必要がありました:、PrimeNGを使用する新しい形にアップグレードすると、アプリケーションのブートストラップでこれを含めるには

~

import {NgForm, FORM_DIRECTIVES, NgModel} from '@angular/forms'; 
import {CORE_DIRECTIVES} from '@angular/common'; 

子コンポーネントでは、これらのインポートは不要です。 [(ngModel)]のどこにでも[ngModelOptions]="{standalone: true}"を含める必要があります。したがって、私の場合:

<p-dropdown [(ngModel)]="actions" [ngModelOptions]="{standalone: true}"></p-dropdown> 
1

私はそれをまだテストしていませんが、私が読んだところでは、あなたのアプリケーションを更新して新しいフォームを使用し、古い非推奨バージョンを無効にする必要があるようです。

import {bootstrap} from '@angular/platform-browser-dynamic'; 
import {provide} from '@angular/core'; 
import {AppComponent} from './app.component' 
import {disableDeprecatedForms, provideForms} from '@angular/forms'; 

bootstrap(AppComponent, [ 
    disableDeprecatedForms(), 
    provideForms(), 
]); 

関連リソース https://github.com/primefaces/primeng/issues/549#issuecomment-230305403

http://forum.primefaces.org/viewtopic.php?f=35&t=46115&p=144059&hilit=no+value+accessor+for#p144059

EDIT!

ネストされたコンポーネントの場合、親コンポーネントがそのコンポーネントを制御できるように、子コンポーネント内にコントロール値アクセサを実装する必要があります。 私はカスタムトグルコンポーネントを実装する例がありますが、このコンポーネントはまた、トグルコンポーネントを使用します。子コンポーネントがどのように見えるか

これは、次のとおりです。

import {Component,Input, Provider, forwardRef} from '@angular/core' 
 
import {ControlValueAccessor, NG_VALUE_ACCESSOR, CORE_DIRECTIVES} from '@angular/common'; 
 

 
import {ToggleButton} from 'primeng/primeng' 
 

 
const noop =() => {}; 
 

 
const CUSTOM_VALUE_ACCESSOR = new Provider(
 
    NG_VALUE_ACCESSOR, { 
 
     useExisting: forwardRef(() => CustomToggle), 
 
     multi: true 
 
    }); 
 

 
@Component({ 
 
    selector: 'custom-toggle', 
 
    template: `<span> 
 
        <p-toggleButton 
 
        [(ngModel)]="value" > 
 
        </p-toggleButton> 
 
       </span>`, 
 
    directives: [CORE_DIRECTIVES,ToggleButton], 
 
    providers: [CUSTOM_VALUE_ACCESSOR] 
 
}) 
 

 
export class CustomToggle implements ControlValueAccessor {   
 
      
 
    private _value: string; 
 
    
 
    private _onTouchedCallback: (_:any) => void = noop; 
 
    private _onChangeCallback: (_:any) => void = noop; 
 
    
 
    get value(): any { return this._value}; 
 
    
 
    set value(v: any) { 
 
     if (v !== this._value) { 
 
      this._value = v; 
 
      this._onChangeCallback(v); 
 
     } 
 
    } 
 
    
 
    onTouched() { 
 
     this._onChangeCallback; 
 
    } 
 
    
 
    writeValue(value: any) { 
 
     this._value = value; 
 
    } 
 
    
 
    registerOnChange(fn: any) { 
 
     this._onChangeCallback = fn; 
 
    } 
 
    
 
    registerOnTouched(fn: any) { 
 
     this._onTouchedCallback = fn; 
 
    } 
 
    
 
}

そして、これは、それが親コンポーネント内で使用することができる方法であるmyToggleは単なるブールある

<custom-toggle [(ngModel)]="myToggle" ></custom-toggle> 

変数。制御値アクセサを実装する方法の

詳細は: http://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel

+0

「ネスト」の問題があるようです。私はあるコンポーネントを別のコンポーネントに注入しようとしています。親コンポーネントはフォームを持ちます。他のコンポーネント(この記事で概説したもの)がそのフォームに注入されています。 'ngModelがフォームタグ内で使用されている場合、name属性を設定するか、フォームコントロールをngModelOptions'で 'スタンドアロン'として定義する必要があります。提案された変更を加えた後でも、同じエラーが続く。 – BrianRT

+0

そのため、ドロップダウンは子コンポーネント内にあります。右? 親と同様>子>ドロップダウン? –

+0

はい、まさに正しいです。 – BrianRT