更新:Link to Plunker角ControlValueAccessor registerOnChange回調被覆蓋
運行到一個奇怪的問題。我正在使用Angular 2.4.1。當組件最初加載時,值設置器運行並正確觸發onChangeCallback。不過,我在consoleChangeChangeCallback上進行日誌記錄,並且在初始設置之後,它將被替換爲匿名函數。
下面是的console.log的結果:
- 功能(_){}
功能(newValue)以{ dir.viewToModelUpdate(NEWVALUE); control.markAsDirty(); control.setValue(newValue,{emitModelToViewChange:false}); }
功能(_){}
第一發生在頁面加載,隨後立即2.我假設角是處理該令牌,並且在該點上正確執行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;
}
}
您是否多次使用'SelectResizableComponent'? console.log可以從組件的第二次使用中運行。 – Adam
不,它只被使用一次。每次我選擇一個新項目時,調用者都會被調用,並且會調用一個空的回調函數。你可以在我剛剛添加的蹦牀上玩。 –
我設置了一個getter和setter來查看函數是否正在更改,但事實並非如此。 https://plnkr.co/edit/kE2wDNAsiczDmRqCXm67?p=preview我沒有給你答案,但有兩個實例是由於某種原因而創建的,這是開始調查的地方。 – Adam