Angular 2/11中能否实现类似微软Razor局部视图的Partial Component功能?
Angular 11 纯HTML局部模板Master/Detail实现方案
Angular 11 可以在不配置路由的前提下实现无对应组件类的纯HTML子视图调用,完全满足你提到的直接在master组件中加载view1~viewn的HTML文件、无需编写子组件ts、无需手动传递上下文的需求,具体实现方式如下:
实现步骤
1. 自定义全局HTML导入指令
仅需编写一次指令,即可全局用于加载外部纯HTML模板,自动继承父组件上下文:
import { Directive, Input, OnInit, ViewContainerRef, Injector, ChangeDetectorRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Compiler, Component, NgModule, CommonModule } from '@angular/core'; @Directive({ selector: '[htmlInclude]' }) export class HtmlIncludeDirective implements OnInit { @Input() htmlInclude: string; constructor( private vcRef: ViewContainerRef, private http: HttpClient, private compiler: Compiler, private injector: Injector ) {} ngOnInit() { // 拉取外部HTML模板内容 this.http.get(this.htmlInclude, { responseType: 'text' }).subscribe(htmlStr => { // 动态创建临时组件承载模板 @Component({ template: htmlStr }) class DynamicTplComponent {} @NgModule({ declarations: [DynamicTplComponent], imports: [CommonModule] }) class DynamicTplModule {} // 编译模板并创建组件实例 const moduleFactory = this.compiler.compileModuleAndAllComponentsSync(DynamicTplModule); const compFactory = moduleFactory.componentFactories.find(item => item.componentType === DynamicTplComponent); const componentRef = this.vcRef.createComponent(compFactory, 0, this.injector); // 自动绑定父组件全部上下文,无需手动传参 const parentContext = this.vcRef.parentInjector.get(ChangeDetectorRef).context; Object.assign(componentRef.instance, parentContext); componentRef.changeDetectorRef.detectChanges(); }); } }
将该指令在你项目的共享模块中声明并导出,即可全局使用。
2. 配置TS类型支持(可选)
如果你的项目TS校验会拦截HTML文件导入,可以在src目录下的global.d.ts声明文件中添加以下配置:
declare module '*.html' { const content: string; export default content; }
3. Master组件中调用子视图
直接在master.component.html中指定要加载的HTML模板路径即可,模板内可以直接访问master组件的所有变量和方法:
<!-- 直接加载view1的纯HTML模板 --> <div htmlInclude="./view1.component.html"></div> <!-- 动态切换不同子视图 --> <div [htmlInclude]="`./view${currentViewIndex}.component.html`"></div>
注意事项
- 该方案运行时编译依赖Angular的JIT编译器,如果你需要使用AOT编译,可以在构建阶段提前把所有子HTML模板打包为静态字符串传入,无需运行时拉取和编译,性能和官方组件基本一致。
- 该模式不属于Angular官方推荐的最佳实践,Angular14及以上版本提供的独立组件可以实现更轻量化的子视图管理,无需注册到NgModule,仅需极简单的组件类即可实现相同效果。
内容的提问来源于stack exchange,提问作者GotRakija
相关产品推荐
相关产品推荐

