-
Notifications
You must be signed in to change notification settings - Fork 25k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get a ViewContainerRef for a provider that is passed to bootstrap to load components #9293
Comments
Could you update the description to mean "get a ViewContainerRef for a provider that is passed to |
We can't create a In general, your service needs a way to attach the change detector of a component to Angular. As far as I understand this issue, that should be enough. Could you confirm? We already have As a workaround, inject |
+1000, had the same issue with my modal component, had to force user to set a default Didn't want to use private method, @tbosch can you confirm it will go get exposed in the future and won't change? |
@pkozlowski-opensource the suggestion from @tbosch should suffice. However, this will force you to use direct DOM access to add that element, then use Another option is to have the overlay as a root of another angular application via bootstrap. |
@tbosch doesn't seem to be enough, unless I'm wrongly interpreting what you are saying. Here is what I've tried: http://plnkr.co/edit/HI6W52QtJ5Hc7zYR1KdU?p=preview @shlomiassaf I don't want to hack around this use case, IMO it is common enough (modal, tooltips, popovers - any overly in general) that we want to have a canonical solution in the framework. |
@pkozlowski-opensource I did some searching and found that there are several offered solutions to solve this, from different places - they all end up at the same block. The main issue is that you can not get access to the In this case you're referring to the top-level root component, but it's the same to any component. I'm not sure using the DI is the way to go since there are 1-n root components - a token won't help. #9254 for example, want's the same feature but from a From there, if you have access to the App root @jelbourn hinted he is working on some sort of solution to this, angular/components#715 (comment) To recap - expose the |
Not sure I follow. In any case we are really not that much interested in
In this issue I was referring to "root component" as the one that is used to bootstrap an app and there can be only one component like this for any given app.
I think it is backwards - you insert components inside view containers, not other way around. Once again, let's not jump in all directions - there is a specific use-case and we need non-hacky solution. |
@pkozlowski-opensource I'm not jumping into conclusions, i'm expressing my opinion. I'm not the one deciding so there's no harm here.
That's exactly As a side note, |
I have created my own modal implementation and it requires 2 things:
I'm not using templates, each modal is separate component with its own template. Currently i'm using static variables to share root view and injector, perhaps service is better idea. Lack of dynamic content in you plunker could be solved using component inheritance. ng-content could help (as declarative way) but it is separate problem of its own (#8937 and others). Inheritance currently is also broken in many ways, so it will be much cleaner solution to use base popup class as container for dynamic components: load base class -> load modal class into base class. Adobe Flex framework used to have FlexGlobals class that had static topLevelApplication field and SystemManager/PopupManager singletons to manage popups, tooltips, overlays and etc., Java Swing has SwingUtilities class to get extra knowledge about component tree. HTML is different, using CSS you could turn anything into modal dialog. |
@pkozlowski-opensource Your plunker shows 2 use cases:
To fix your plunker, you need to register the change detectors of both! See this plunker: http://plnkr.co/edit/tHlSZLObdAuCPZ3ZX6DY?p=preview This uses the following non public API:
To fix this, we should:
However, in general, these problems are only caused because the popup service is a provider passed to I.e. I am not sure whether we want to support this use case in general... |
Also note that calling |
@tbosch OK, I see now that you need to register both component and an embedded view change detectors, cheers for this!
But then would I still be able to move nodes outside of the bootstrapped application? Asking since with |
|
@pkozlowski-opensource I know you don't like it, but I'v spent hours on this and learned the linker by heart :) I have already tried all of the solutions above, and other workarounds. Having You will be able to compose a templateless component with multiple child-component from a service, without any issues and no need to declare I'm 99% sure of this, but I will be happy to be wrong and get an answer, I'm dealing with dialogs since alpha 26 or something... @tbosch just a simple question, if i'm creating a component using component factory, why is it that I can't get access to the |
If you will load such components dynamically how are you going to make template bindings as we used to use? |
@Zigzag95 see http://plnkr.co/edit/25o8wO7ruAAwKktJAggC?p=preview Usually it should be some top level components added via code, the rest via templating system. |
I am having exactly the same issue, I have a service whereby I want to create my own modal component but have it placed at the end of the app component, but without the ViewContainerRef I am finding this to be impossible. |
Until this feature is implemented I've been using this to get the root ViewContainerRef. It's in no way the correct way to do it but it gets the job done.
|
OK, I shall check one tomorrow. But I have to say there is a use case here and I do feel that an official solution should provided. |
@dsara I check your suggestion this morning and i may work, aside from the fact that I need to provide a dependancy for my service and it would appear to place the new component outside of the app component instead of within the component. If it were the latter then the provider already exists and there would not be a problem. It is essential that I am able to create the component within the scope of the app component, not concerned if it the last item or not, prefer it at the end though. |
@HeavenlyHost I've used this method to add a modal service to my application. It doesn't need to inherit any existing providers other than the ApplicaionRef. Originally I was unable to get the ApplicationRef provider by passing it to the constructor of the service because I'm loading the modal service during bootstrap so I had to provide the injector and then manually inject the ApplicationRef provider when opening the modal. I don't know if this method might allow you to get existing providers but I thought I'd post it and see if it might help you. If this doesn't work you might have to get one of the first child components below the app component and then load to next to that location instead of the root. It would be nice to have a function that instead of "loadNextToLocation" you could "loadWithinLocation" or something like that so you could dynamically load a component as a child of an existing component instead of next to it.
|
+1 |
Facing a similar challenge, posted my question on SO and wanted to reference here - http://stackoverflow.com/questions/39857222/angular2-dynamic-component-injection-in-root |
This feature is useful to allow components / embedded views to be dirty checked if they are not placed in any `ViewContainer`. Closes angular#9293
This feature is useful to allow components / embedded views to be dirty checked if they are not placed in any `ViewContainer`. Closes angular#9293
This feature is useful to allow components / embedded views to be dirty checked if they are not placed in any `ViewContainer`. Closes angular#9293
This feature is useful to allow components / embedded views to be dirty checked if they are not placed in any `ViewContainer`. Closes angular#9293
@vicb - I'm curious given my question above on SO and this new commit, if there is a better way now to address that issue. My hack is actually broken in 2.2 now as well. |
@amcdnl i had success following material2 starting https://github.com/angular/material2/blob/master/src/lib/core/portal/dom-portal-host.ts#L44-L73 |
@scttcper - Ok that actually helped. I was able to abstract out all their specific logic and make this work standalone service. Here is the code for others:
|
@amcdnl I seem to have gotten this working with the above code, but something is happening with change detection. Have you had a similar issue?
|
@patrickmichalina - I have not ran into this, shoot me a email amcdaniel2 at gmail |
@amcdnl it appears this is because I have dynamicly rendered components within dynamically rendered components. Using the older, hacky method, everything worked fine, but now with Angular 2.2.0+ those are no longer available. Your code works on the first dynamic components, but failing for the nested ones (which doesn't make sense). So I think it is me using a combination of methods that is causing the problem. I will investigate further and post if the issue persists after I refactor using this newer appRef.attachView API |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
I'm submitting a ... (check one with "x")
Current behavior
I can't get (inject)
ViewContainerRef
s for a top-level (application) component.Expected/desired behavior
Should be able to inject
ViewContainerRef
s for a top-level (application) component as it might be needed to dynamically load a component from a service.Reproduction of the problem
http://plnkr.co/edit/eM3ibINNHgGB7Y2GyC4i?p=preview
What is the motivation / use case for changing the behavior?
There is a class of widgets (modals, popovers, tooltips etc.) that:
body
)Taking all the above we need to dynamically create a component (modal window) and provide projectable nodes (modal content). To make projectable nodes "live" we need a
ViewContainerRef
but since we are in a service we don't have access to anyViewContainerRef
- hence the request.@tbosch I was discussing this use-case yesterday with @mhevery and he advised to open an issue / discuss it with you.
Related: #8941
The text was updated successfully, but these errors were encountered: