Angular2 rc6 检查后表达式发生了变化
Angular2 rc6 Expression has changed after it was checked
我已按照 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()解决;但不能在开发中使用它
****错误(Chrome 输出):
core.umd.js:5995 异常:./MFormComponent class MFormComponent 中的错误 - 内联 template: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)
我猜这是因为您对 <custom-component>
和 <input>
使用相同的 formControlName="surename1"
。
如果你想将它们绑定到同一个模型,那么只需指向它 ngModel
但为每个模型创建一个控件。
我已按照 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()解决;但不能在开发中使用它
****错误(Chrome 输出):
core.umd.js:5995 异常:./MFormComponent class MFormComponent 中的错误 - 内联 template: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)
我猜这是因为您对 <custom-component>
和 <input>
使用相同的 formControlName="surename1"
。
如果你想将它们绑定到同一个模型,那么只需指向它 ngModel
但为每个模型创建一个控件。