2016-08-25 57 views
9

假设我有一个Angular2组件<my-button>,我想为点击按钮时显示的下拉菜单中的渲染选项提供输入。我有菜单组件为<my-menu>,并有条件地呈现在<my-button>模板是否有通过选项。Angular2渲染组件到身体

也许我可以绝对位置内<my-button><my-menu>达到理想的定位。但也许我不能,因为我有一个包含元素overflow:hidden,这将夹<my-menu>。因此,我需要在<body>中渲染<my-menu>,并将其绝对定位到<my-button>

有没有办法将<my-menu>改为<body>,即使它被放置在<my-button>的模板中?

谢谢!

回答

1

不,没有。

您可以在AppComponent之外引导组件,并使用共享服务进行通信。

https://github.com/angular/angular/issues/9293中讨论了关于动态创建组件作为AppComponent的兄弟的一些讨论,但尚不清楚这可能着陆的时间,方式或时间。

+0

内部渲染'AppComponent'可能会被罚款,无需引导额外的事情。但是,你能否详细说明使用共享服务进行通信?主要是,如何在组件树上完全不同的位置呈现菜单和按钮,然后将两者关联起来? – Comptonburger

+1

应该在https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service –

+0

@GünterZöchbauer中进行解释,正如我在下面的评论中所述的那样,许多样板和无处不在的功能需要能够向''添加任意组件:模块,工具提示,类似咆哮的通知,菜单如OP描述...任何想法如何在2.0.x(GA)中实现这些功能? – AndyPerlitch

1

是的,你可以。既然你没有提供代码,我不能给你一个更新的例子。但是,当我构建模态系统时,我以此为基础:https://github.com/shlomiassaf/angular2-modal

当我们初步拉入时,它不是很可重用,但有一种方法可以通过ApplicationRef获取根节点。 (这是回到了Angular 2 beta 8)

这绝对是可行的。

更新: 您可以使用ApplicationRef获取要注入的位置,并使用DynamicComponentLoader注入新组件。使用下面的线路上,hostLocation(在DynamicComponentLoader的loadIntoLocation方法的第二个参数)将会把元素只是在HTML您的应用程序组件后:

this.appRef['_rootComponents'][0].location 

appRef是引用传递到我的组件的构造函数中ApplicationRef

您可以使用beta.8以后出现的其他元素或方法来获得您想要的效果。

这里还有一个很好的网站有很多的例子:https://medium.com/tixdo-labs/angular-2-dynamic-component-loader-752c3235bf9#.x913qdh4u

+0

'DynamicComponentLoader'仍然可用于angular2 GA吗?我找不到关于它的文档,它似乎与ComponentResolver有一定的联系,它完全不赞成使用'Compiler'。 – AndyPerlitch

+0

它实际上看起来好像您提供的medium.com博客链接不再适用于angular2 – AndyPerlitch

+0

@AndyPerlitch--这就是为什么我用我使用的测试版标记了示例。我认为我仍然可以在RC 1中做到这一点,但是我不得不直接链接到一个更深的文件,而不是在主包中暴露出来,这是角色团队建议不要做的。自从RC 1开始我没有尝试过,但我可以在最终版本中尝试它。 – ps2goat

7

你能做到这一点,但它是复杂的。

  1. 添加您的动态组件模块declarationsentryComponents
  2. 获取参考根ViewContainerRef它注射到你的应用程序组件。
  3. 获取对ComponentFactoryResolver的参考,也使用注射。
  4. 使用这样的事情:

    private resolverFactory:ComponentFactoryResolver; 
    private viewContainer:ViewContainerRef; 
    
    var compFactory:ComponentFactory<Frame> = this.resolverFactory.resolveComponentFactory(Frame); 
    
    var cmpRef:ComponentRef<Frame> = this.viewContainer.createComponent(compFactory, this.viewContainer.length); 
    
  5. 除去成分:

    cmpRef.destroy(); 
    
1

如果要加载组件有条件,你可以使用ComponentResolverFactory的。

所有您需要做的就是让一个viewContainerRef实例&使用编译器随时更新它。

我会建议为所有要动态加载的组件创建一个单独的模块&异步加载它们。

也许下面的答案可以帮助你更好的方式。

Load Components Dynamically