【发布时间】:2021-06-27 16:14:50
【问题描述】:
我有一个像下面这样的组件
<select #tabSelect (change)="tabLoad($event.target.value)" class="mr-2">
<option value="tab1">First tab</option>
<option value="tab2">Second tab</option>
</select>
<div class="tab-content">
<div class="tab-pane fade show active">
<ng-template #tabContent></ng-template>
</div>
</div>
有两个选项卡,它们调用 tabLoad() 函数并发送参数单击哪个选项卡。
export class DemoComponent implements OnInit {
@ViewChild('tabContent', { read: ViewContainerRef }) entry: ViewContainerRef;
activeTab: any = 'tab1';
constructor(private resolver: ComponentFactoryResolver) { }
ngOnInit() {
this.tabLoad(this.activeTab);
}
tabLoad(page) {
setTimeout(() => {
this.activeTab = page;
this.entry.clear();
if (page == 'tab1') {
const factory = this.resolver.resolveComponentFactory(Tab1Component);
console.log(this.entry);
this.entry.createComponent(factory);
} else if (page == 'tab2') {
const factory = this.resolver.resolveComponentFactory(Tab2Component);
this.entry.createComponent(factory);
}
}, 500);
}
}
在这个 .ts 文件中,我创建了一个名为 entry 的变量,它指向 #tabContent.Tab 内容加载组件取决于哪个页面处于活动状态。
我为此行为编写了一个测试套件,如下所示
fdescribe('DemoComponent', () => {
let component: DemoComponent;
let fixture: ComponentFixture<DemoComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterModule.forRoot([]), SharedModule],
declarations: [Tab1Component, Tab2Component],
}).compileComponents().then(() => {
fixture = TestBed.createComponent(DemoComponent);
component = fixture.componentInstance;
});
}));
it('should set activeTab correctly and clear entry when tabLoad is called', fakeAsync(() => {
component.tabLoad("tab1");
flush();
expect(component.activeTab).toBe('tab1');
}));
});
当我调用 this.entry.clear(); 时,此测试失败并显示 Cannot read property 'clear' of undefined; . console.log(this.entry); 也打印未定义。
然后我决定在 .compileComponents().then(() => {}) 范围内添加fixture.detectChanges(),但仍然以同样的方式失败。但是当我在 ng serve 之后转到页面时,一切正常。
【问题讨论】:
-
要修复当前的测试,你需要在
fakeAsync里面添加fixture.detectChanges(),但实际上超时很奇怪,500看起来像一个神奇的数字,为什么不用ngAfterViewInit来代替 -
@PetrAveryanov 因为我需要在点击标签时触发标签加载。如何使用 ngAfterViewInit 来做到这一点?
标签: javascript angular typescript jasmine karma-runner