angular 2: trying to load a component dynamically, getting: TypeError: Cannot read property 'parentInjector'
angular 2: trying to load a component dynamically, getting: TypeError: Cannot read property 'parentInjector'
我正在尝试使用 angular2 动态加载组件,但出现错误:
异常:错误:未捕获(承诺):类型错误:无法读取未定义的 属性 '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)
});
}
}
有什么想法吗?
问候
肖恩
您最初的错误是由于实际 class 名称与您尝试动态渲染的组件名称不匹配造成的:即,如果您引用 TestComponent
class 也必须命名为 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
:
public LoadComponentAsync(componentPath:string, componentName:string,
locationAnchor:ViewContainerRef) {
System.import(componentPath)
.then(fileContents => {
console.log(fileContents);
return fileContents[componentName]
})
.then(component => {
this.resolver.resolveComponent(component).then(factory => {
locationAnchor.createComponent(factory, 0, locationAnchor.injector);
});
});
}
tx 全部支持,此代码从 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);
}
}
对我来说,这是因为我使用的是 ng2-bootstrap 的模态对话框,我没有在根组件中包含对 viewContainerRef
的引用。
我正在尝试使用 angular2 动态加载组件,但出现错误:
异常:错误:未捕获(承诺):类型错误:无法读取未定义的 属性 '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)
});
}
}
有什么想法吗?
问候
肖恩
您最初的错误是由于实际 class 名称与您尝试动态渲染的组件名称不匹配造成的:即,如果您引用 TestComponent
class 也必须命名为 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
:
public LoadComponentAsync(componentPath:string, componentName:string,
locationAnchor:ViewContainerRef) {
System.import(componentPath)
.then(fileContents => {
console.log(fileContents);
return fileContents[componentName]
})
.then(component => {
this.resolver.resolveComponent(component).then(factory => {
locationAnchor.createComponent(factory, 0, locationAnchor.injector);
});
});
}
tx 全部支持,此代码从 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);
}
}
对我来说,这是因为我使用的是 ng2-bootstrap 的模态对话框,我没有在根组件中包含对 viewContainerRef
的引用。