我已经按照http://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel教程创建了一个自定义元素。
有一个表单有两个字段:一个自定义组件和另一个组件(输入字段)通过ngmodel链接到同一个字段。
当我在自定义组件中编辑该值时,它抛出异常“原始异常:表达式在选中后已更改”。。但是,normal字段中的更改将正确触发对自定义元素的更改。
这是代码:

<custom-component [control]="surname1" [(ngModel)]="person.surname1" [name]="'surname1'" formControlName="surname1">Add surname:</custom-component>

<input type="text" name="surname2" id="surname2" formControlName="surname1" [(ngModel)]="person.surname1" />

以及自定义元素:
const noop = () => {};

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

@Component({
    selector: 'custom-component',
    template: `<label><ng-content></ng-content></label>
                    <input type="text"  name="{{name}}" [(ngModel)]="value"
                        (ngModelChange)="changed($event)"

                        (blur)="onBlur()"
                    />
    `,
    providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class CustomComponent implements ControlValueAccessor {

    @Input() control: FormControl;
    @Input() name: any;
    private innerValue: any = '';

    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
    changed(event) {
        this.onTouchedCallback();
    }

    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;
    }
}

它在使用enableProdMode()时解决;但不能在开发中使用
****错误(Chrome输出):
js:5995异常:错误在./mformccomponent类mformccomponent-inline模板:55:117中,原因是:表达式在检查后已更改。上一个值:“surtest”。当前值:“surtes”。
js:5997原始异常:表达式在检查后已更改。上一个值:“surtest”。当前值:“surtes”
在ExpressionChangedAfterithasbeenCheckederror.error处(本机)
在expressionChangedAfterithasbeenCheckederror.baseerror[作为构造函数](http://localhost:8085/templatetest/js/@angular/core/bundles/core.umd.js:1456:38
在新的表达式更改时,检查错误(http://localhost:8085/templatetest/js/@angular/core/bundles/core.umd.js:8078:20

最佳答案

我想这是因为你对formControlName="surename1"<custom-component>使用了相同的<input>
如果要将它们绑定到同一个模型,则只需指向该模型,但为每个模型创建一个控件。

09-25 18:07
查看更多