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
Support for dynamic Angular Elements / Webcomponents (with Renderers) #35328
Comments
|
Hi there, we too make heavy use of the @angular/element package in order to build custom elements. (The term "Web Components" is something created by google. You won't find anything in the W3C / WHATWG specs). And I can totally ensure that this works. Maybe not with the standard functionalities provided by angular, but still we solved it. Without going to much into detail, you could just simply do following:
window.myCustomElementRegistry = new Set(); // when loading the page
// ....
// customElement registriation
customElements.define(myTag, FooClass); // assuming does not error
window.myCustomElementRegistry.add(myTag);Not you are able to
You may need to create a link between specific bundle.js and its tagname somehow (this is what i meant with 'more information') e.g. the server could response like this {
"elements": [
{ "tag": "my-tag", "file": "my-bundle.js" }
]
}This way you would know how to load the bundle and how to create an instance. Hope I could help. Cheers |
|
@flash-me thanks for the reply but you are addressing something completely else than the original issue so I would rather remove it to not confuse the readers, thank you |
|
I'm pretty sure I'm not. |
|
@flash-me you speak about registering custom elements... The issue itself focuses on being able to NOT hard-code tags in templates of Angular components and being able to override them ALSO in IVY using Angular renderers... For example Angular component template: Which should then be rendered by Angular as SO as you can see its NOT about where the tag is coming from BUT about the last step where we want to render other tag that was provided in the component template WHILE being able to still use standard template bindings like So again please move that in other issue... edit: plus it already works in ViewEngine and IVY, the only problem being that the IVY solution is fragile and I would like to improve it with more robust approach to overriding used renderer... |
|
No, I won't. Ok, your problem is different. But The way you initially described it was not that clear. Qutestion: Why not using TemplateRefs? |
|
@flash-me library already uses template refs and in ViewEngine all we need to do is to set new tag to template data structure like
and this works and renders the element with provided tag, BUT in IVY the template is a function not a data structure that's why we have to use renderers to override the tag as the last step before rendering, again please keep this issue focused... EDIT: Again this was already discused in original issue
|
|
@flash-me so I would suggest we delete this whole thread and leave the original issue as it describes other problem and it should focus on that |
|
Sorry mate to disappoint you, but I'm not going to delete anything except I assaulted someone. if that's the case, just tell me the exact sentence and i will apologize. for your surprise, we also make heavy usage of the micro Frontends approach with angular. And really performant by the way. Even if you will find a solution for your problem, your intented use case is very questionable.
Pretty simple. Thats what Inputs in Angular Components and Attributes/Properties in DOM Elements are meant for. You want to completely change the logic for the same tag which has been already defined on the browser context. That means, between two instances of the same tag I could get completely different things loaded by a backend?
If you want to inject additional content in your page without refresh, then there are better ways, as I already mentioned previously. Cheers |
|
@flash-me again you write about stuff which does NOT relate to the issue so please open a other issue where you can solve what you want or need and let this focused, I opened it after chat with Rob who told me to do it. I believe your concerns are valid just that they DO NOT relate to this use case, so please move to new place where it can be discussed appropriatelly... |
|
Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends. Find more details about Angular's feature request process in our documentation. |
|
For reference, here is the current impl which allows dynamically override rendered tag with IVY |
|
Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage. We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package. You can find more details about the feature request process in our documentation. |
|
@tomastrajan Can't you provide your own And then overwrite |
|
@jpzwarte maybe, but the way I understand it is that all this is outdated as Renderer 2 is for VE which was now removed and Angular 13 is IVY only which might use something else ? |
|
The comment here implies that Ivy also uses this? But I don't know exactly how Ivy renders to the DOM. :/ |
|
Code is from master btw (so angular 13). |
|
I think |
Relevant Package
The functionality relates to the
@angular/platform-browserpackage as this is the package which implementsDomRendererFactory2andDefaultDomRenderer2Description
Angular Elements and Webcomponents in general represent great solution for various real world use cases like...
Usual approach to consuming Angular Elements and Web components leaves us with 2 options:
<some-element [prop]="value">document.createElement('some-element');...The library
@angular-extensions/elementssolves this by enabling both lazy loading and standard Angular template binding<some-element *axLazyElement="bundle.js" [prop]="value">and this works with both ViewEngine and IVY...Dynamic element use case
In previous section we're committing to element being
<some-element>by hard-coding it into template of the consumer Angular component. What if we wanted to support loading element configuration at runtime (eg from backend) to enable fully dynamic microfrontends?As it turns out this works too (at least for the ViewEngine) so it is possible to write
<ax-lazy-element *axLazyElementDynamic="'some-element'; url: 'bundle.js'" [prop]="value"></ax-lazy-element>.The bundle will be lazy loaded, and then the element will be rendered as
<some-element>.The only thing needed to do that is to override value of the
tagNamein theTemplateRefof the*axLazyElemendDynamicdirective and Angular will render desired element supporting our use case.Now this does NOT work with IVY since in IVY template is an function.
Rob @robwormald gave me hint that it should be possible to override
Renderer(or use custom) to hook into rendering and override element there.The Issue
It is possible to achieve that with render BUT:
DomRendererFactory2andDefaultDomRenderer2are private so it is NOT possible to extend them and hence I would need to re-implement the whole renderer which sounds pretty excessive and hard to maintainRootRenderer?Current solution
Play around with live demo (which serves both lib and demo and rebuilds on changes to any of them) using this one liner
git clone https://github.com/angular-extensions/elements.git elements && cd elements && npm ci && npm startonce it runs, please navigate toExamples > Dynamicto see it in action.Describe the solution you'd like
Probably being able to easily extend default renderer and being able to register it like we're used to with interceptors or control value accessors.
I would like to give people option (or do it for them behind the scenes) to do
Describe alternatives you've considered
I spent quite some time trying to override tag inside of template function without success
The text was updated successfully, but these errors were encountered: