【问题标题】:Custom component with NgModel throws: No provider for CustomInputComponent带有 NgModel 的自定义组件抛出:没有 CustomInputComponent 的提供者
【发布时间】:2017-11-03 12:34:38
【问题描述】:

我刚刚开始学习 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注册。

为什么它不起作用?

【问题讨论】:

  • 希望你在 app.module.ts 中注册了这个组件

标签: angular


【解决方案1】:

您似乎忘记用 @Component 装饰器注释您的 CustomInputComponent

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    相关资源
    最近更新 更多