【问题标题】:Angular2 rc6 Expression has changed after it was checkedAngular2 rc6 表达式在检查后发生了变化
【发布时间】:2017-01-20 20:14:22
【问题描述】:

我已按照http://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel 上的教程创建自定义元素。

有一个表单有两个字段:一个自定义组件和另一个组件(输入字段)通过 ngmodel 链接到同一个字段。

当我在自定义组件中编辑值时,它会抛出异常“ORIGINAL EXCEPTION: Expression has changed after it was checked.”。但是,普通字段的更改会正确触发自定义元素的更改。

这是代码:

<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() 时解决;但不能在开发中使用它

****ERROR(Chrome 输出)

core.umd.js:5995 例外:./MFormComponent 类 MFormComponent 中的错误 - 内联模板:55:117 原因:检查后表达式已更改。以前的值:'surtest'。当前值:“surtes”。

core.umd.js:5997 原始异常:检查后表达式已更改。以前的值:'surtest'。当前值:'surtes'

在 ExpressionChangedAfterItHasBeenCheckedError.Error(本机) 在 ExpressionChangedAfterItHasBeenCheckedError.BaseError [作为构造函数] (http://localhost:8085/templatetest/js/@angular/core/bundles/core.umd.js:1456:38) 在新的 ExpressionChangedAfterItHasBeenCheckedError (http://localhost:8085/templatetest/js/@angular/core/bundles/core.umd.js:8078:20)

【问题讨论】:

  • 能否请您添加完整的错误消息。据我记得,错误消息包含有关导致错误的表达式的信息。
  • 我添加到问题中,不确定它是否有助于解决问题

标签: angular typescript custom-component


【解决方案1】:

我猜这是因为您对&lt;custom-component&gt;&lt;input&gt; 使用相同的formControlName="surename1"
如果您想将它们绑定到同一个模型,那么只需将ngModel 指向它,而是为每个模型创建一个控件。

【讨论】:

  • 是的,它可以工作,虽然想使用相同的控件名称(认为会有一种在兄弟组件中传播更改的方法,但在类似的帖子中没有找到。将保留作为解决方案。
猜你喜欢
  • 1970-01-01
  • 2017-12-27
  • 2019-01-05
  • 1970-01-01
  • 2018-11-17
  • 2019-05-29
  • 1970-01-01
相关资源
最近更新 更多