Angular 12动态加载组件直接传入Component类报错如何解决?
问题解答
为什么直接传入Component类会触发TS报错
支持直接向ViewContainerRef.createComponent()传入组件类的重载签名是Angular 13版本才新增的特性,你当前使用的是Angular 12,该版本的createComponent方法仅支持接收ComponentFactory类型的入参,不支持直接传入组件类,所以会出现类型不匹配的TS报错。你参考的官方文档说明是Angular 13及以后版本的规范,不适用于Angular 12的运行环境。
Angular 12 正确的动态加载组件写法
你最终使用的基于ComponentFactoryResolver的写法就是Angular 12官方推荐的标准写法,需要补充注意以下细节:
- 首先要在对应模块的
declarations和entryComponents数组中声明需要动态加载的组件,Angular 12及更早版本动态加载的组件必须加入entryComponents数组,否则运行时会抛出异常:
// 对应模块文件示例 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RecentGridComponent } from './recent-grid/recent-grid.component'; import { SearchFiltersComponent } from './search-filters/search-filters.component'; import { ResultAreaDirective } from './result-area.directive'; @NgModule({ declarations: [ SearchFiltersComponent, RecentGridComponent, ResultAreaDirective ], imports: [BrowserModule], entryComponents: [RecentGridComponent], // 必须添加该行 bootstrap: [SearchFiltersComponent] }) export class AppModule { }
- 组件侧的标准写法如下:
import { Component, ComponentFactoryResolver, OnInit, ViewChild } from '@angular/core'; import { RecentGridComponent } from '../recent-grid/recent-grid.component'; import { ResultAreaDirective } from '../result-area.directive'; @Component({ selector: 'app-search-filters', templateUrl: './search-filters.component.html', styleUrls: ['./search-filters.component.sass'] }) export class SearchFiltersComponent implements OnInit { @ViewChild(ResultAreaDirective) resultArea!: ResultAreaDirective constructor(private resolver: ComponentFactoryResolver) { } ngOnInit(): void { } loadMore() { const viewContainerRef = this.resultArea.viewContainerRef; // 可选:如果需要先清空容器内已有组件再加新组件,可以调用clear方法 // viewContainerRef.clear(); const factory = this.resolver.resolveComponentFactory(RecentGridComponent) const componentRef = viewContainerRef.createComponent<RecentGridComponent>(factory); // 后续可通过componentRef.instance访问组件实例,完成传值、事件订阅等操作 } }
补充说明
如果想要使用直接传入组件类的简化写法,需要将项目的Angular版本升级到13.0.0及以上,升级后不需要再使用ComponentFactoryResolver,也不需要将动态组件加入entryComponents数组。
内容的提问来源于stack exchange,提问作者Henrique Milli
相关产品推荐
相关产品推荐

