在 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
    }
  ]
})