2016-07-06 79 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

相关问题