在 Angular 中使用控制值访问器时出错
Error when using Control Value Accessor in Angular
我已经在我的应用程序中实现了控制值访问器,但是当 运行 应用程序时,我收到以下错误消息:
ERROR TypeError: dir.valueAccessor.writeValue is not a function
at setUpControl (forms.js:2578)
at FormGroupDirective.addControl (forms.js:6318)
at FormControlName._setUpControl (forms.js:6969)
at FormControlName.ngOnChanges (forms.js:6892)
at checkAndUpdateDirectiveInline (core.js:24499)
at checkAndUpdateNodeInline (core.js:35163)
at checkAndUpdateNode (core.js:35102)
at debugCheckAndUpdateNode (core.js:36124)
at debugCheckDirectivesFn (core.js:36067)
at Object.eval [as updateDirectives] (AnnouncementInformationListComponent.html:82)
我是这样设置的:
AnnouncementInformationListComponent.html
<form [formGroup]="_form">
<div [formArrayName]="item.code">
<div *ngFor="let controlItem of _form.get(item.code).controls; let ctrlIndex = index"
class="form-row"
[formGroupName]="ctrlIndex">
<div [ngClass]="{'col-8': oneParameter(item), 'col-4': twoParameters(item), 'col-3': threeParameters(item)}"
*ngFor="let param of item.parameters; let arrIndex = index">
<div [ngSwitch]="param">
<input *ngSwitchCase="blabla(param)"
type="text"
class="form-control form-control-sm"
formControlName="{{arrIndex}}"
[placeholder]="getInputPlaceholder(item, arrIndex)"
[ngbTypeahead]="search"
placement="bottom-left">
<div *ngSwitchCase="blablabla(param)">
Search
<app-multi-select
[data]="data"
[displaySmall]="true"
[displayLabel]="false"
[removeValueAfterEvent]="true"
[useInForm]="true"
(onSelectedItemEvent)="selectedItemEventHandler($event, item)"
formControlName="{{arrIndex}}">
</app-multi-select>
</div>
<div *ngSwitchDefault>
<input type="text"
class="form-control form-control-sm"
formControlName="{{arrIndex}}"
[placeholder]="getInputPlaceholder(item, arrIndex)">
</div>
</div>
<button *ngIf="isblabla(item)" type="button" class="btn btn-secondary btn-sm col-2" (click)="onClickEvent(controlItem.value, item, ctrlIndex)" container="body" tooltip="blabla">
<span >
<fa-icon icon="arrows-alt-h" [styles]="{'stroke': 'white', 'color': 'white'}"></fa-icon>
</span>
</button>
<ng-container
*ngTemplateOutlet="arrayItemButtonsTmpl; context: {item:item, ctrlIndex:ctrlIndex, arrayLength: _form.get(item.code).controls.length}">
</ng-container>
</div>
</div>
</form>
多select.component.ts
@Component({
selector: 'app-multi-select',
templateUrl: './multi-select.component.html',
styleUrls: ['./multi-select.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AnnouncementInformationListComponent),
multi: true
}
]
})
多select.component.ts
export class MultiSelectComponent implements OnInit, ControlValueAccessor {
value: string;
多select.component.ts
writeValue(value: string): void {
this.value = value ? value : ''
}
registerOnChange(fn: any): void {
}
registerOnTouched(fn: any): void {
}
setDisabledState?(isDisabled: boolean): void {
}
值得注意的是 AnnouncementInformationListComponent.html 中的所有其他输入字段(未使用控制值访问器)都工作正常。此外,当我 google 错误消息时,我很难找到其他遇到同样问题的人,我觉得这很奇怪。知道问题可能是什么吗?
Angular 尝试在您的 AnnouncementInformationListComponent 中找到 writeValue 函数,因为您将其声明为对 MultiSelectComponent 提供程序数组的引用。
将您的提供商更改为:
@Component({
selector: 'app-multi-select',
templateUrl: './multi-select.component.html',
styleUrls: ['./multi-select.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MultiSelectComponent),
multi: true
}
]
})
我已经在我的应用程序中实现了控制值访问器,但是当 运行 应用程序时,我收到以下错误消息:
ERROR TypeError: dir.valueAccessor.writeValue is not a function
at setUpControl (forms.js:2578)
at FormGroupDirective.addControl (forms.js:6318)
at FormControlName._setUpControl (forms.js:6969)
at FormControlName.ngOnChanges (forms.js:6892)
at checkAndUpdateDirectiveInline (core.js:24499)
at checkAndUpdateNodeInline (core.js:35163)
at checkAndUpdateNode (core.js:35102)
at debugCheckAndUpdateNode (core.js:36124)
at debugCheckDirectivesFn (core.js:36067)
at Object.eval [as updateDirectives] (AnnouncementInformationListComponent.html:82)
我是这样设置的:
AnnouncementInformationListComponent.html
<form [formGroup]="_form">
<div [formArrayName]="item.code">
<div *ngFor="let controlItem of _form.get(item.code).controls; let ctrlIndex = index"
class="form-row"
[formGroupName]="ctrlIndex">
<div [ngClass]="{'col-8': oneParameter(item), 'col-4': twoParameters(item), 'col-3': threeParameters(item)}"
*ngFor="let param of item.parameters; let arrIndex = index">
<div [ngSwitch]="param">
<input *ngSwitchCase="blabla(param)"
type="text"
class="form-control form-control-sm"
formControlName="{{arrIndex}}"
[placeholder]="getInputPlaceholder(item, arrIndex)"
[ngbTypeahead]="search"
placement="bottom-left">
<div *ngSwitchCase="blablabla(param)">
Search
<app-multi-select
[data]="data"
[displaySmall]="true"
[displayLabel]="false"
[removeValueAfterEvent]="true"
[useInForm]="true"
(onSelectedItemEvent)="selectedItemEventHandler($event, item)"
formControlName="{{arrIndex}}">
</app-multi-select>
</div>
<div *ngSwitchDefault>
<input type="text"
class="form-control form-control-sm"
formControlName="{{arrIndex}}"
[placeholder]="getInputPlaceholder(item, arrIndex)">
</div>
</div>
<button *ngIf="isblabla(item)" type="button" class="btn btn-secondary btn-sm col-2" (click)="onClickEvent(controlItem.value, item, ctrlIndex)" container="body" tooltip="blabla">
<span >
<fa-icon icon="arrows-alt-h" [styles]="{'stroke': 'white', 'color': 'white'}"></fa-icon>
</span>
</button>
<ng-container
*ngTemplateOutlet="arrayItemButtonsTmpl; context: {item:item, ctrlIndex:ctrlIndex, arrayLength: _form.get(item.code).controls.length}">
</ng-container>
</div>
</div>
</form>
多select.component.ts
@Component({
selector: 'app-multi-select',
templateUrl: './multi-select.component.html',
styleUrls: ['./multi-select.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AnnouncementInformationListComponent),
multi: true
}
]
})
多select.component.ts
export class MultiSelectComponent implements OnInit, ControlValueAccessor {
value: string;
多select.component.ts
writeValue(value: string): void {
this.value = value ? value : ''
}
registerOnChange(fn: any): void {
}
registerOnTouched(fn: any): void {
}
setDisabledState?(isDisabled: boolean): void {
}
值得注意的是 AnnouncementInformationListComponent.html 中的所有其他输入字段(未使用控制值访问器)都工作正常。此外,当我 google 错误消息时,我很难找到其他遇到同样问题的人,我觉得这很奇怪。知道问题可能是什么吗?
Angular 尝试在您的 AnnouncementInformationListComponent 中找到 writeValue 函数,因为您将其声明为对 MultiSelectComponent 提供程序数组的引用。
将您的提供商更改为:
@Component({
selector: 'app-multi-select',
templateUrl: './multi-select.component.html',
styleUrls: ['./multi-select.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MultiSelectComponent),
multi: true
}
]
})