带有NgModel的自定义组件抛出:没有CustomInputComponent的提供者

时间:2017-11-03 12:34:38

标签: angular

我刚刚开始学习Angular 2,现在我尝试使用带有NgModel的自定义组件。我创建了一个select组件,我在其他组件中重用,现在我需要将它传递给选定的值。

要做到这一点,我已经从Plunker复制了这个工作示例。

但是当我尝试使用它时,我收到了消息:

No provider for CustomInputComponent

这是自定义组件打字稿:

import { Component, Inject, Output, EventEmitter, forwardRef } from '@angular/core';
import { Http, RequestOptions, Headers } from '@angular/http';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { ILaw } from '../../interfaces/law.interface';

const noop = () => {
};

export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => CustomInputComponent),
    multi: true
};

@Component({
    selector: 'law',
    templateUrl: './law.component.html',
    providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})

export class LawComponent {
    public laws: ILaw[];
    public selectedLaw: number;

    @Output()
    notifyParent: EventEmitter<number> = new EventEmitter<number>();

    constructor(private http: Http,
        @Inject('BASE_URL') private baseUrl: string) {

        http.get(baseUrl + 'api/Law').subscribe(result => {
            this.laws = result.json() as ILaw[];
            console.log(this.laws);
        }, error => console.error(error));
    }

    lawChanges() {
        console.log("selected law: " + this.selectedLaw);
        this.notifyParent.emit(this.selectedLaw);
    }
}

export class CustomInputComponent implements ControlValueAccessor {

    //The internal data model
    private innerValue: any = '';

    //Placeholders for the callbacks which are later provided
    //by the Control Value Accessor
    private onTouchedCallback: () => void = noop;
    private onChangeCallback: (_: any) => void = noop;

    //get accessor
    get value(): any {
        return this.innerValue;
    };

    //set accessor including call the onchange callback
    set value(v: any) {
        if (v !== this.innerValue) {
            this.innerValue = v;
            this.onChangeCallback(v);
        }
    }

    //Set touched on blur
    onBlur() {
        this.onTouchedCallback();
    }

    //From ControlValueAccessor interface
    writeValue(value: any) {
        if (value !== this.innerValue) {
            this.innerValue = value;
        }
    }

    //From ControlValueAccessor interface
    registerOnChange(fn: any) {
        this.onChangeCallback = fn;
    }

    //From ControlValueAccessor interface
    registerOnTouched(fn: any) {
        this.onTouchedCallback = fn;
    }
}

它的html:

<select [(ngModel)]="value" (change)="lawChanges()">
    <option></option>
    <option *ngFor="let law of laws" [value]="law.lawId">{{law.name}}</option>
</select>

这是我使用law组件的地方:

<law (notifyParent)="getNotification($event, rowIndex)" [(ngModel)]="productionorder.lawId"></law>

我一直在寻找,但我找不到任何有用的东西,这似乎不是很容易做到(或者除非我不明白怎么做,因为我有样品发现非常复杂)。

我一直在使用law组件,而在其他组件中没有任何问题,但现在我需要将新选择的值传递给它。它也在app.module.shared.ts注册。

为什么不起作用?

1 个答案:

答案 0 :(得分:0)

您似乎忘了使用CustomInputComponent装饰器

来展开@Component