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

Router 3.0.0-beta.1 и Forms 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'; 

в компоненте ребенка, такой импорт не нужны. Вы должны указать [ngModelOptions]="{standalone: true}", где бы ни находился [(ngModel)]. Итак, в моем случае:

<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!

Для вложенных компонентов вам необходимо реализовать Access Item Accessor внутри дочернего компонента, чтобы позволить родительскому компоненту контролировать его. У меня есть пример, где я реализую пользовательский компонент переключения, но этот компонент также использует компонентный компонент ng.

Это как ребенок компонент выглядит следующим образом:

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'. Даже после внесения предложенных изменений такая же ошибка сохраняется. – BrianRT

+0

Таким образом, выпадающее меню находится внутри дочернего компонента. Правильно? Как родительский> ребенок> выпадающий список? –

+0

Да, точно. – BrianRT

Смежные вопросы