我有一个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