5

我只是想将下拉菜单中的数据与ngModel. 当应用程序加载时我收到一个错误,这是有道理的。

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

这使我相信该错误源于ngModel应用程序加载时最初未与任何数据绑定的事实。

我不是最擅长使用 Observables ......所以要小心。

部分 html 下拉列表

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

相关 TypeScript(排除导入)

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不会破坏应用程序,但也许我误解了错误。最终,我希望绑定所选项目,并且我认为克服此错误将使我达到这一点。

4

2 回答 2

2

我尚未对其进行测试,但从我所读到的内容看来,您似乎必须更新您的应用程序才能使用新表单并禁用旧的弃用版本。

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

编辑!

对于嵌套组件,您必须在子组件内实现控制值访问器,以允许父组件控制它。我有一个例子,我实现了一个自定义切换组件,但是这个组件也使用了 Prime 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

于 2016-07-06T17:22:23.573 回答
2

事实证明,我介于使用已弃用的 Angular 表单和新的 Angular 表单之间。要使用 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>
于 2016-07-07T15:47:40.803 回答