遇到一个奇怪的问题。我正在使用Angular 2.4.1。组件最初加载时,值setter运行并且onChangeCallback正确触发。但是,我是控制台记录onChangeCallback,在最初设置之后,它被替换为匿名函数。
以下是console.log的结果:
function(newValue){ dir.viewToModelUpdate(NEWVALUE); control.markAsDirty(); control.setValue(newValue,{emitModelToViewChange:false}); }
function(_){}
第一个发生在页面加载,紧接着是2.我假设Angular正在处理令牌并且此时正确实现ControlValueAccessor。当我然后对select元素进行更改时,onChangeCallback再次被称为匿名函数,而没有添加ControlValueAccessor。
有关如何解决此问题的任何想法?只有这种形式控制才能解决这个问题。
import { Component, Input, Output, EventEmitter, forwardRef, ViewChild, ElementRef, Renderer, ChangeDetectorRef, OnChanges } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'select-resizable',
template:`
<select #mainSelectElement [(ngModel)]="value" (change)="updateSelected($event.target.value)" style="width: initial;">
<ng-content></ng-content>
</select>
<select class="usa-sr-only" aria-hidden="true" role="presentation" #hiddenSelectElement style="width: initial;">
<option>{{value}}</option>
</select>
`,
providers: [
{ provide: NG_VALUE_ACCESSOR, useClass: forwardRef(() => SelectResizableComponent), multi: true }
]
})
export class SelectResizableComponent implements ControlValueAccessor {
@ViewChild('hiddenSelectElement') hiddenSelectElement: ElementRef;
@ViewChild('mainSelectElement') mainSelectElement: ElementRef;
private _selected: any;
private onChangeCallback: (_: any) => void = (_: any) => {};
private onTouchedCallback: () => void = () => {};
get value(): any {
return this._selected;
}
set value(val: any) {
this._selected = val;
this.onChangeCallback(val);
console.log(this.onChangeCallback);
}
constructor(private renderer: Renderer, private ref: ChangeDetectorRef) {}
updateSelected(event) {
this.ref.detectChanges();
const width = (this.hiddenSelectElement.nativeElement.clientWidth * 1.02) + 'px';
this.renderer.setElementStyle(this.mainSelectElement.nativeElement, 'width', width);
}
writeValue(val: any) {
this.value = val;
}
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any) {
this.onTouchedCallback = fn;
}
}
答案 0 :(得分:2)
providers: [
{ provide: NG_VALUE_ACCESSOR, useClass: forwardRef(() => SelectResizableComponent), multi: true }
]
问题就在那里。我使用useClass
而不是useExisting
提供了令牌。因此,在实例化组件之后,从NG_VALUE_ACCESSOR标记的组件类创建了一个新值。
感谢Adam,因为他发现我有两个值。