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

时间:2016-07-12 10:29:37

标签: dynamic angular components

我正在尝试在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收到此错误: 错误:无法使用“DashboardComponent”解析组件。在新的BaseException $ 1(http://localhost:63815/lib/@angular/compiler//bundles/compiler.umd.js:971:27

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

另一方面,假设我的Dashboard组件加载了导入的其他内容...... Systemjs将自动处理所有这些,不是吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

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

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

之前,一切正常

由于 moduleId 的值仅在运行时已知,因此webpack将无法在编译时解析实际的模块组件,也不会捆绑这些文件。

如果您希望将动态模块组件作为单个 app.js 的一部分捆绑在一起,则需要在代码中的某个位置进行动态模块组件的静态导入p>