简体   繁体   English

Angular2将组件渲染到body

[英]Angular2 render component to body

Say I have an Angular2 component <my-button> and I want to give an input for options to render in a dropdown menu shown when the button is clicked. 假设我有一个Angular2组件<my-button> ,我想在单击按钮时显示的下拉菜单中为要渲染的选项提供输入。 I have the menu component as <my-menu> and it renders conditionally in the template of <my-button> if there are options passed in. 我将菜单组件作为<my-menu> ,如果传入了选项,它会在<my-button>模板中有条件地呈现。

Maybe I can just absolutely position <my-menu> within <my-button> to achieve the desired positioning. 也许我可以绝对在<my-button>定位<my-menu> <my-button>来实现所需的定位。 But maybe I can't because I have overflow:hidden on a containing element and that would clip <my-menu> . 但也许我不能,因为我有overflow:hidden在一个包含元素,并将剪辑<my-menu> So instead I need to render <my-menu> in <body> and position it absolutely to <my-button> . 所以我需要在<body>渲染<my-menu> <body>并将其绝对定位到<my-button>

Is there a way to render <my-menu> to <body> even though it is placed inside the template for <my-button> instead? 有没有办法将<my-menu>渲染到<body>即使它被放在<my-button>的模板中呢?

Thanks! 谢谢!

You can do that, however it is complicated. 你可以这样做,但它很复杂。

  1. Add your dynamic component to module declarations and entryComponents 将动态组件添加到模块declarationsentryComponents
  2. Get reference to root ViewContainerRef injecting it to your application component. 获取对根ViewContainerRef引用,将其注入应用程序组件。
  3. Get reference to ComponentFactoryResolver , also using injection. 获取对ComponentFactoryResolver引用,也使用注入。
  4. Use something like this: 使用这样的东西:

     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. Removing component: 删除组件:

     cmpRef.destroy(); 

No, there isn't. 不,没有。

You can bootstrap a component outside your AppComponent and communicate using a shared service instead. 您可以在AppComponent外部引导组件,并使用共享服务进行通信。

Some discussion about dynamically creating components as sibling to the AppComponent are discussed in https://github.com/angular/angular/issues/9293 but it's not clear if, how, or when this might land. 有关动态创建组件作为AppComponent兄弟的讨论, AppComponent https://github.com/angular/angular/issues/9293,但目前尚不清楚它是否,如何或何时落地。

Yes, you can. 是的你可以。 Since you didn't provide code, I can't give you an updated example. 由于您没有提供代码,我不能给您一个更新的示例。 However, when I built a modal system, I used this as a base: https://github.com/shlomiassaf/angular2-modal 但是,当我构建模态系统时,我使用它作为基础: https//github.com/shlomiassaf/angular2-modal

When we initially pulled it in, it wasn't very reusable, but there's a way to get the root node via ApplicationRef . 当我们最初将其拉入时,它不是非常可重用,但有一种方法可以通过ApplicationRef获取根节点。 (This was back around Angular 2 beta 8.) (这是围绕Angular 2 beta 8。)

It's definitely doable. 这绝对可行。

UPDATE: You can use an ApplicationRef to get the location to inject into, and a DynamicComponentLoader to inject your new component. 更新:您可以使用ApplicationRef获取要注入的位置,使用DynamicComponentLoader注入新组件。 Using the following line as your hostLocation (second parameter in DynamicComponentLoader's loadIntoLocation method) will put the element just after your app component in the html: 使用以下行作为hostLocation (DynamicComponentLoader的loadIntoLocation方法中的第二个参数)将元素放在html中的app组件之后:

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

appRef is the reference to the ApplicationRef that is passed into my component's constructor. appRef是对ApplicationRef的引用,它传递给我的组件的构造函数。

You may be able to play with other elements or methods that came out after beta .8 to get the effect you desire. 您可以使用测试版.8之后出现的其他元素或方法来获得您想要的效果。

Here's another good site with a lot of examples: https://medium.com/tixdo-labs/angular-2-dynamic-component-loader-752c3235bf9#.x913qdh4u 这是另一个很好的网站,有很多例子: https//medium.com/tixdo-labs/angular-2-dynamic-component-loader-752c3235bf9#.x913qdh4u

If you want to load a component conditionally you can make use of ComponentResolverFactory. 如果要有条件地加载组件,可以使用ComponentResolverFactory。

All You need to do is to have one viewContainerRef instance & update it using compiler wherever you want. 您需要做的就是拥有一个viewContainerRef实例并使用编译器随时随地更新它。

I will recommend creating a separate module for all the components you want to load dynamically & load them asynchronously. 我建议为要动态加载的所有组件创建一个单独的模块,并异步加载它们。

Perhaps below answer could help you in better way. 也许低于答案可以更好地帮助你。

Load Components Dynamically 动态加载组件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM