2016-07-06 80 views
4

我只是試圖綁定數據從下拉菜單與ngModel。當應用程序加載時收到的錯誤是有道理的。PrimeNG下拉選定的項目數據綁定

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

這使我相信,錯誤是從ngModel最初沒有綁定時,應用程序加載的任何數據的事實而產生。

我不是最好的使用Observables ...所以要小心。

部分的HTML下拉

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

相關打字稿(不含進口)

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

原來我是在使用過時的角形式和新角形式之間的中間。要使用PrimeNG,升級到新的形式,包括這在你的應用程序的引導:

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

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

然後,在我實例的形式,我的父組件,我不得不改變從進口:

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

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

編輯!

對於嵌套組件,您必須在子組件內實現一個控件值訪問器,以便父組件可以控制它。 我有一個例子,我實現了一個自定義切換組件,但是這個組件也使用了主切換組件。

這是子組件的樣子:

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; 
 
    } 
 
    
 
}

這是它如何能夠在母組件內使用

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

哪裏myToggle僅僅是一個布爾變量。

更多關於如何實現控制值訪問: http://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel

+0

似乎有一個「嵌套」問題。我試圖將一個組件注入到另一個組件中。父組件有一個表單。另一個組件(本文中概述的組件)正在被注入該表單。現在我得到了'如果在表單標籤內使用ngModel,則必須設置name屬性或者必須在ngModelOptions中將表單控件定義爲'standalone'。即使在進行建議的更改後,同樣的錯誤仍然存​​在。 – BrianRT

+0

所以下拉是在子組件內。對? 像父母>孩子>下拉? –

+0

是的,完全正確。 – BrianRT