Angular 2 - 使用 ComponentResolver 加载在运行时下载的组件

Posted

技术标签:

【中文标题】Angular 2 - 使用 ComponentResolver 加载在运行时下载的组件【英文标题】:Angular 2 - Use ComponentResolver to load component downloaded at runtime 【发布时间】:2016-11-14 13:00:36 【问题描述】:

我正在尝试在我的 Angular2 应用程序中动态加载一个组件。 通过动态,我不仅仅意味着将父组件模板中缺少的组件插入到 DOM 中;我的意思是从服务器下载另一个组件,因为用户可能永远不需要它,然后将它插入到 DOM 中。 所以我跟着 this 了解如何使用 Systemjs 加载组件,现在我看到,在 RC4 中,我们需要使用 this 和 ComponentResolver 将东西注入 DOM。

所以这是我的模块包装器组件的代码,它应该把东西放在一起:

export class ModuleWrapperComponent implements OnInit 
    @ViewChild("module",  read: ViewContainerRef ) target: ViewContainerRef;
    @Input() isOpen: boolean;
    @Input() moduleId: number;
    type: string = null;
    moduleRef: ComponentRef<any> = null;

    private isViewInitialized: boolean = false;

    constructor(private resolver: ComponentResolver)  

    private _loadModule(moduleId: number): Promise<string> 
        if (!!this.type)
            return Promise.resolve(this.type);

        var mod = 
            component: "DashboardComponent",
            path: "/app/modules/dashboard.component"
        ;
        return System
            .import(mod.path)
            .then(() => this.type = mod.component);
    

    updateComponent() 
        if (!this.isViewInitialized)
            return;

        if (!!this.moduleRef)
            this.moduleRef.destroy();

        if (this.isOpen) 
            this._loadModule(this.moduleId)
                .then(type => 
                    this.resolver.resolveComponent(type)
                        .then(factory => 
                            this.moduleRef = this.target.createComponent(factory)
                            // to access the created instance use
                            // this.compRef.instance.someProperty = 'someValue';
                            // this.compRef.instance.someOutput.subscribe(val => doSomething());
                        );
                )
        
    

    ngOnChanges() 
        this.updateComponent();
    

    ngAfterViewInit() 
        this.isViewInitialized = true;
        this.updateComponent();
    

    ngOnDestroy() 
        if (!!this.moduleRef)
            this.moduleRef.destroy();
    

遗憾的是,我从 ComponentResolver 收到此错误: 错误:无法使用“仪表板组件”解析组件。在新的 BaseException$1 (http://localhost:63815/lib/@angular/compiler//bundles/compiler.umd.js:971:27)

我认为在 Systemjs 中加载模块是不够的......那么我如何告诉 ComponentResolver 我已经下载了一个新组件?官方文档还很年轻,还很缺乏……

顺便说一句,假设我的仪表板组件通过导入加载了其他内容...Systemjs 会自动处理所有这些,不是吗?

提前致谢!

【问题讨论】:

【参考方案1】:

这并不能完全回答您的问题。

但是, 我们有类似的需求,并且正在使用 SystemJs 动态加载组件。 在我们开始考虑构建和部署策略并遇到 Webpack

之前,一切都运行良好

由于 moduleId 的值只有在运行时才知道,所以 webpack 将无法在编译时解析实际的模块组件,也不会打包这些文件。

如果您希望将动态模块组件捆绑为单个 app.js

【讨论】:

以上是关于Angular 2 - 使用 ComponentResolver 加载在运行时下载的组件的主要内容,如果未能解决你的问题,请参考以下文章

404 使用 Angular2、angular2-websocket 和类型

使用 Angular CLI 的 Angular 2 材质

Angular 5 + OAuth2:未使用库设置令牌 [angular-oauth2-oidc]

Angular2-signaturepad 与 Angular 一起使用会导致找不到模块错误

Angular 5 Angular Material 2 - 使用 minLength 自动完成

如何使用 Angular cli 在 Angular 2 中导入电子