我正在做什么:
Plnkr示例 - > 在此处输入链接描述
在该示例中,您将看到"AddItem"方法
addItem(componentName:string):void{
let compFactory: ComponentFactory;
switch(componentName){
case "image":
compFactory = this.compFactoryResolver.resolveComponentFactory(PictureBoxWidget);
break;
case "text":
compFactory = this.compFactoryResolver.resolveComponentFactory(TextBoxWidget);
break;
}
//How can I resolve a component based on string
//so I don't need to hard cost list of possible options
this.container.createComponent(compFactory);
Run Code Online (Sandbox Code Playgroud)
}
"compFactoryResolver:ComponentFactoryResolver"在构造函数中注入.
正如您将注意到的,必须对switch语句中的每个排列进行硬编码都不太理想.
将ComponentFactoryResolver记录到控制台时,我发现它包含一个包含各种工厂的Map.
CodegenComponentFactoryResolver {_parent: AppModuleInjector, _factories: Map}
Run Code Online (Sandbox Code Playgroud)
但是,这张地图是私人的,无法轻易访问(据我所知).
有没有更好的解决方案然后以某种方式滚动我自己的类来访问这个工厂列表?
我看过很多关于人们试图创建动态组件的消息.但是,这些通常是在运行时创建组件.这里讨论的组件已经预先定义,我试图使用字符串作为键来访问工厂.
任何建议或建议都非常感谢.
非常感谢你.
我正在做的事情:
这是我正在尝试做的一个Plnkr.Plnker - > https://plnkr.co/edit/XpDCGIwd2at9oR74lpY5?p=preview
当用户单击"+组件"时,以下内容将创建组件
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(ChildComponent);
let ref = this.container.createComponent(componentFactory);
Run Code Online (Sandbox Code Playgroud)
在添加的每个子组件中,当用户单击"Fire Event"时
<span class="initiateParentAction"
(click)="fireEventEmitter()" [class.eventFired]="eventFired==true">Fire Output Event: {{eventFired}}</span>
Run Code Online (Sandbox Code Playgroud)
它称之为以下
fireEventEmitter(){
console.log("Event Fired");
this.parentActionReq.emit({
action: "helloWorld"
});
this.eventFired = true;
setTimeout(() => this.eventFired=false, 2000);
}
Run Code Online (Sandbox Code Playgroud)
父组件(在本例中为"App"组件)正在侦听这些输出,如此处所示
<ng-container #container
(parentActionReq)="childActionInitiated($event)"></ng-container>
Run Code Online (Sandbox Code Playgroud)
我无法从动态创建的组件中获取事件以向父级注册.在Plnker中,"Received child output Event"应该变为true.
在这一点上,我认为由于这些组件是在运行时添加的,我需要以某种方式重新初始化事件检测OnInit.但没有取得进展.
任何建议,提示,指导将在这里表示赞赏.
我对于创建我自己的Observables的道路犹豫不决,因为这似乎是重新创建了轮子,输出完全符合我的目的.
非常感谢你.
我正在努力完成的总结
ViewContainerRef(完成)问题
ViewContainerRefViewContainerRef提供方法,例如get(index)return ViewRef。ViewRef似乎与Component实例没有任何关系,这使得获取所需数据成为一项挑战这是一个 Stackblitz 链接,其工作代码如下所示(用于动态创建组件)
在appComponent通过创建使用一些部件开始了ComponentFactoryResolver,并且将它们添加到ViewChild在模板中所定义。每个DynamicComponent都使用id我们在创建后尝试引用的属性值进行初始化
@Component({
selector: "my-app",
template: `
<h3>Retrieving Component Reference for Dyamic Compnents</h3>
<button (click)="getCompRef()">Get References</button>
<div>
<ng-container #childCont></ng-container>
</div>
<div>
<small>List out the Ids from the dynamic components</small> <br />
{{ createdItemIds | json }}
</div>
`,
styleUrls: ["./app.component.css"]
})
export class AppComponent implements AfterViewInit …Run Code Online (Sandbox Code Playgroud) 我正在尝试做的事情:
Plnkr -> http://plnkr.co/edit/Do4qYfDLtarRQQEBphW3?p=preview
在查看 angular.io 文档时,我发现“Injector”可用于获取构造函数中的父组件
constructor(private el: ElementRef, private hostComponent:Injector){
el.nativeElement.draggable = 'true';
}
Run Code Online (Sandbox Code Playgroud)
在这样做时,我得到了 Injector Object。据我所知,我应该使用
this.hostComponent.get(INJECTORTOKEN)
Run Code Online (Sandbox Code Playgroud)
我难以理解的问题是,Angular 中提供的示例假设您知道要在令牌中提供的 Component 类型。IE:
this.hostComponent.get(Image);
this.hostComponent.get(Box);
Run Code Online (Sandbox Code Playgroud)
在 pnkr 示例中,我的模板中有两个组件
<div>
<h2>Hello {{name}}</h2>
<my-image></my-image> <!-- Uses the "My Directive" -->
<my-box></my-box> <!-- Uses the "My Directive" -->
</div>
Run Code Online (Sandbox Code Playgroud)
我的问题是,在“mydirective.ts”中。当我不知道父组件是“my-image”还是“my-box”组件时,如何利用“injector.get()”。
在提供的示例中,指令被触发“ondrag()”。查看控制台,获取日志消息。
非常感谢任何帮助。
非常感谢你。