angular 2:尝试动态加载组件,得到:TypeError:无法读取属性'parentInjector'

时间:2016-06-01 20:23:54

标签: angular systemjs

我正在尝试使用angular2动态加载组件,并且错误输出:

EXCEPTION:错误:未捕获(在承诺中):TypeError:无法读取未定义的属性'parentInjector'

这是代码:

@Component({
    selector: 'Notes5',
    template: `<span #extensionAnchor></span>`
 })

export class Notes5 extends NotesBase {
    constructor(private dynamicComponentLoader:DynamicComponentLoader, private NotesService:NotesService,
                protected sliderPanel:Sliderpanel,
                protected commBroker:CommBroker) {

        this.LoadComponentAsync("src/comps/app2/notes/NoteDynamic", "TestComponent", this.extensionAnchor);
    }

    @ViewChild('extensionAnchor', {read: ViewContainerRef}) extensionAnchor:ViewContainerRef;

    public LoadComponentAsync(componentPath:string, componentName:string, locationAnchor:ViewContainerRef) {
        System.import(componentPath)
            .then(fileContents => {
                console.log(fileContents);
                return fileContents[componentName]
            })
            .then(component => {
                this.dynamicComponentLoader.loadNextToLocation(component, locationAnchor)
            });
    }
}

任何想法?

问候

肖恩

3 个答案:

答案 0 :(得分:3)

您的原始错误是由实际类名与您尝试动态呈现的组件名称不匹配引起的:IE,如果您引用TestComponent,则该类也必须命名为{{1} }。

您当前的错误TestComponent是由于您在构建器中调用它之前尝试在呈现视图之前将内容加载到TypeError: Cannot read property 'parentInjector'元素中而导致的。您需要在生命周期内进一步调整呼叫,例如@ViewChild

ngAfterViewInit

最后,由于不推荐constructor(private dynamicComponentLoader:DynamicComponentLoader, private NotesService:NotesService, protected sliderPanel:Sliderpanel, protected commBroker:CommBroker, private resolver: ComponentResolver) { } ngAfterViewInit() { this.LoadComponentAsync("src/comps/app2/notes/NoteDynamic", "TestComponent", this.extensionAnchor); } ,您应该使用DynamicComponentLoader代替:

ComponentResolver

答案 1 :(得分:0)

tx all for the support,此代码适用于rc.1

import {
    Component, Inject, Injectable, provide, ComponentResolver, ComponentRef,
    ViewContainerRef, ViewChild
} from '@angular/core';
import {Sliderpanel} from "../../sliderpanel/Sliderpanel";
import {CommBroker} from "../../../services/CommBroker";
import {NotesBase} from "./NotesBase";
import {CountDown} from "../../countdown/CountDown";


@Injectable()
class NotesService {
    constructor(@Inject("NotesConfigValue")
                public config:{noteDefault:string}) {
    }

    showConfigValue() {
        // show the passed in param via provide("NotesConfigValue",asterisklue: {noteDefault: 'example of passing param to component via DI'}}),
        console.log(this.config.noteDefault);
    }
}


@Component({
    selector: 'Notes5',
    directives: [CountDown],
    providers: [
        // NotesService get's provided with a noteDefault
        NotesService,
        provide("NotesConfigValue", {useValue: {noteDefault: 'example of passing param to component via DI'}}),
    ],
    template: `<button type="button" (click)="onPrev($event)" class="btn btn-default btn-sm">
                    <span class="fa fa-arrow-left "></span>
                </button>
                <hr/>
                <small>I am notes5 component</small>
                <span #extensionAnchor></span>




                `
})
export class Notes5 extends NotesBase {
    constructor(private componentResolver:ComponentResolver, private NotesService:NotesService,
                protected sliderPanel:Sliderpanel,
                protected commBroker:CommBroker) {
        super(sliderPanel, commBroker);
        NotesService.showConfigValue();
        this.me = this;
        this.slideRight = 'notes4';


    }

    @ViewChild('extensionAnchor', {read: ViewContainerRef}) extensionAnchor:ViewContainerRef;

    public LoadComponentAsync(componentPath:string, componentName:string, locationAnchor:ViewContainerRef) {
        System.import(componentPath)
            .then(fileContents => {
                return fileContents[componentName]
            })
            .then(component => {
                this.componentResolver.resolveComponent(component).then(factory => {
                    locationAnchor.createComponent(factory, 0,
                        locationAnchor.injector);
                });
            });


    }

    ngAfterViewInit() {
        this.LoadComponentAsync("src/comps/app2/notes/NoteDynamic", "NoteDynamic", this.extensionAnchor);
    }
}

答案 2 :(得分:0)

对我而言,这是因为我使用的是ng2-bootstrap的模态对话框,而且我没有在根组件中包含对viewContainerRef的引用。