我有一個select
元素在我的模板如下:角2更新選擇在單位更改模型試驗
<select [(ngModel)]="snapshotCriteria.salesArea" required>
<option *ngFor="let salesArea of salesAreas" [ngValue]="salesArea">
{{salesArea.name}}
</option>
</select>
你可以看到,該模型必然會snapshotCriteria.salesArea
這是一個對象,所以我們使用ngValue
代替value
。屬性本身也是一個對象。
的成分如下:
export class Component implements OnInit {
salesAreas: SalesArea[];
snapshotCriteria: SnapshotCriteria = {
salesArea: null,
date: null,
startTime: 600,
endTime: 3059
};
constructor(private salesAreaService: SalesAreaService) {}
ngOnInit(): void {
this.salesAreaService.fetchSalesAreas(salesAreas) => this.salesAreas = salesAreas);
}
}
注意,其被綁定到模型select
salesArea
初始化爲null
。
當通過操作下拉菜單通過模板進行更改時,模板正常運行。但是在我的單元測試中,我直接更新了select
元素引用的模型,並且與我期望的相反,視圖沒有更新!由於該字段是必需的,因爲驗證失敗,我的測試無法提交表單。這是測試:
it('...', fakeAsync(() => {
spyOn(salesAreaService, 'fetchSalesAreas').and.returnValue(Observable.of([
{areaNumber: 1, name: 'A'} as any as SalesArea,
{areaNumber: 2, name: 'B'} as any as SalesArea,
{areaNumber: 3, name: 'C'} as any as SalesArea
]));
fixture.detectChanges();
tick();
component.snapshotCriteria = {
salesArea: {areaNumber: 1, name: 'A'} as SalesArea,
date: new Date(2015, 5, 25),
startTime: 1000,
endTime: 1001
} as SnapshotCriteria;
fixture.detectChanges();
tick();
}));
調試顯示select
元素未更新。我嘗試了各種各樣的東西無濟於事:
- 不在測試中重新實例化對象。
- 實例化
salesArea
對象爲空對象而不是null
。 - 調度
input
和change
事件在測試中。 - 在視圖中聆聽
ngModelChange
,但在測試中未觸發 。
記下感興趣的是,通過使用模板中value
了ngValue
,我能夠通過改變底層模型更新視圖。
此行爲是相似,我測試了'select'元素的指令時經歷。我不得不做多個'detectChanges'和'whenStable'(我沒有使用'fakeAsync')調用。嘗試再次調用'fixture.detectChanges();蜱();'。 (我爲此提出了一個[問題](https://github.com/angular/angular/issues/11895),但回想起來,我的repro不是基於測試的,而是專注於其他一些奇怪的行爲,我可能會提出另一個更關注測試的問題) – cartant
@cartant在測試過程中,fixture一直保持穩定,給tick()添加更多調用沒有任何作用。 – Cristian
這是重要的多重'detectChanges'調用。這就是爲我解決的。但是,因爲我沒有使用'fakeAsync',所以我和'whenStable'調用進行了配對。 – cartant