angular-extensions / elements Goto Github PK
View Code? Open in Web Editor NEWLazy load Angular Elements (or any other web components / custom elements ) with ease!
Home Page: https://angular-extensions.github.io/elements/
License: MIT License
Lazy load Angular Elements (or any other web components / custom elements ) with ease!
Home Page: https://angular-extensions.github.io/elements/
License: MIT License
Will this package support angular v10?
Hi,
I have a use case where adding hooks support to @angular-extensions/elements
would be beneficial. This idea is somewhat similar to #30, so maybe they could be implemented at the same time.
Let's take an application with several Angular elements packaged as web components. Naturally, they may have several common dependencies that we may want to load only once per page (for example core Angular packages or ngrx
). In order to improve UX and time to first meaningful paint, we postpone loading these dependencies until the components are requested by the current view.
With the current API of @angular-extensions/elements
I don't see a way this could be easily achieved.
Add hooks to ElementConfig
:
{
url: 'https://my-awesome-component.com',
hooks: {
beforeLoad: () => resolveDependencies('my-component')
}
}
The library will execute beforeLoad
hook before inserting script with the component's JS bundle. If the hook returns a Promise (which is necessary in this particular case), the library will wait for this Promise to resolve before proceeding with the request. If the Promise fails, the corresponding error component is shown instead.
Do you think this API makes sense for @angular-extensions/elements
?
WOuld be cool if it would be possible to ng add @angular-extension/schematics
which will install the package and add LazyElementsModule.forRoot()
with some basic config,... could be also customized using prompts if user wants default configuration or just plain import...
Does this package works with angular version "^10.0.0"?
I tried it and I have got below error.
core.umd.js:4484 ERROR Error: The selector "mf-home" did not match any elements
at DefaultDomRenderer2.selectRootElement (platform-browser.umd.js:987)
at locateHostElement (core.umd.js:7980)
at ComponentFactory.create (core.umd.js:22844)
at ApplicationRef.bootstrap (core.umd.js:29036)
at core.umd.js:28736
at Array.forEach (<anonymous>)
at PlatformRef._moduleDoBootstrap (core.umd.js:28736)
at core.umd.js:28704
at ZoneDelegate.invoke (zone-evergreen.js:364)
at Object.onInvoke (core.umd.js:28133)
Here is my package.json
"dependencies": {
"@angular-extensions/elements": "^10.0.2",
"@angular/animations": "^10.0.0",
"@angular/cdk": "^10.1.3",
"@angular/common": "^10.0.0",
"@angular/compiler": "^10.0.0",
"@angular/core": "^10.0.0",
"@angular/elements": "^10.0.14",
"@angular/flex-layout": "^10.0.0-beta.32",
"@angular/forms": "^10.0.0",
"@angular/material": "^10.1.3",
"@angular/platform-browser": "^10.0.0",
"@angular/platform-browser-dynamic": "^10.0.0",
"@angular/router": "^10.0.0",
"@nrwl/angular": "10.0.12",
"@webcomponents/custom-elements": "^1.4.2",
"@webcomponents/webcomponentsjs": "^2.4.4",
"ngx-build-plus": "^10.1.1",
"rxjs": "~6.5.5",
"zone.js": "^0.10.2"
},
my app.component.html
<mf-home *axLazyElement="elementUrl"> </mf-home>
my app.component.ts
elementUrl = 'assets/bundles/main.f0aedbe8f4f67ea36480.js';
this main.js file is created with help of ngx-build-plus package. This works if I load this js file using script tag.
I can provide complete code if it is required.
Hello @tomastrajan,
I'm trying to test angular-extensions on stackblitz but my project is not working.
https://stackblitz.com/edit/angular-extensions-elements
What I'm missing?
Thank you!
Hi, great job.
You save my day 🥇 but I think a new feature can be added.
Correct me if I am wrong but I think there is a case the library is not covering.
If we are in a shell app, and we want to load several micro-apps (web-elements) dynamically based on an incoming config, the shell shouldn't know about future tag elements.
For example, having this config as available micro-apps/widgets:
[
{ "tag": "micro-app1", "url": "/micro-apps/micro-app1/main.js" },
{ "tag": "micro-app2", "url": "/micro-apps/micro-app2/main.js" }
...
{ "tag": "micro-appN", "url": "/micro-apps/micro-appN/main.js" }
]
If we add a new input (tag) to the lazy-element.directive.ts
, we could replace the original tag by the giving tag.
The usage could look like this:
<div *axLazyElement="'/micro-apps/micro-app1/main.js'; tag: 'micro-app1'"></div>
Being converted to
<micro-app1 *axLazyElement="'/micro-apps/micro-app1/main.js'; tag: 'micro-app1'"></micro-app1>
At least, in my case, the shell app code doesn't know about the incoming config and tag elements and therefore I still have to inject the micro-apps using script elements.
I am trying to load an angular element in another angular application
Lcally everything looks good.have problems running in production build.
Zone already loaded.
Would be nice to add guard that will make sure that the forRoot
was called only once and provide nice error message if that is not the case...
One of the approaches is described in this article by @timdeschryver https://dev.to/angular/guarding-your-angular-modules-lio
PROBLEM
Currently I believe that you can not set webcomponents attributes/properties via angular data binding.
SOLUTION
It would be nice if the directive acts as a wrapper, giving support for properties to be passed to the webcomponent.
PROPOSED TECHINCAL SOLUTION
Add another input to the directives for data to pass to the webcomponent @Input(axLazyElementsDataBinding) dataBinding
using ngOnUpdate detect updates.
Using the angular renderer2 service set the webcomponent's attribute with the updated data
Do you think this would be in scope of this library?
My objective is to display skeleton loading for my web-component. This skeleton loading should be part of the DOM until the first data request from the web-component emits. To accomplish the last part I have added an "intialLoadDone" to my web-component, and it works ok. Something like this:
<!-- Some fancy skeleton loading build with tailwind-->
<div *ngIf="!isDoneLoading">
</div>
<web-cmpt [hidden]="!isDoneLoading" *axLazyElement="URL" (intialLoadDone)="doneLoading()">
</web-cmpt>
The problem is when there is an error loading the web cmpt. How can I make the component aware of this? Is it possible to get notified if there is a problem loading the web component? I hope my question makes sense 😊
Currently, the directive works poorly with OnPush components, since change detection isn't triggered on an element's load. I believe the fix is as simple as calling ChangeDetectorRef.markForCheck() after the element has been loaded and inserted back into the component's view.
Hi
i have angular elements with own ngrx states.
if the parent app use logout, the lazy laoded files doest not clean their own states.
I cannot clear just onDestroy
in own apps because this would reload data each time the user change the route but always logged In.
Ist there a way to archieve this?
Hello @tomastrajan,
I'm trying to have the Angular component instance using bindings with an ax-lazy-element
.
Here a test project https://github.com/BossOz/test-aee-bindings
In my angular element DesktopSystemEmptyElementComponent
I emit the event componentReady
that, unfortunately, is not fired.
here the code of the html
<ax-lazy-element *axLazyElementDynamic="'vdr-empty-component', url: url; module: true"
(componentReady)="onComponentReady($event)">
</ax-lazy-element>
Why this event is not fired?
Is because that the emit is in the ngOnInit()
?
Thank you!
Hello guys!
I'm really new in Angular world so sorry about my questions!
I have some Angular libraries (developed by my colleagues) that are not on npm and I would like to load components that are exported by these.
My libraries are stored in a local folder and I'm trying to lazy load these libraries without success.
<ng-template #loading>Loading...</ng-template>
<ng-template #error>Error loading component</ng-template>
<mycomponent *axLazyElement="this.elementUrl; loadingTemplate:loading; errorTemplate:error; module: true"></mycomponent >
where
elementUrl = "./libraries/mylibrary.js";
So I bring your "basic usage" example that uses mwc-icon.js
and I saved the module url locally
https://unpkg.com/@material/[email protected]/mwc-icon.js?module
Using the remote URL all is working as described.
Switching to the local path (./libraries/mwc-icon.js
) I must change the internal import of the js but everything worked properly!
Now my question is? Is it possible to lazy load my libraries with your @angular-extensions/elements or I need to do some "transformation" to my libraries/components?
Thank you very much!
We need to have reloading capability that could be called whenever a URL fails to load (maybe because of the network issues).
Hi 👋
I have encountered the following issue with this package: it is impossible to dynamically resolve URLs at runtime while still compiling using AOT.
I have a use case where the URL is resolved dynamically at runtime in a sync way. This URL may be configured by the running sub-application or it may be configured by one of web-components.
The API looks somewhat like this:
const lazyElementConfig: LazyElementModuleOptions = {
elementConfigs: [
{ tag: 'ba-menu', url: resolveUrl('ba-menu') }
]
}
My team uses a custom package to store some data on the window object to share it between micro-frontends. This data is resolved before the application's bootstrap.
But during the compilation, Angular aggressively optimizes this value to undefined
, which obviously breaks the application.
Currently, the workaround is to manually provide URLs to the directive in templates.
I think it could be fixed if elementConfigs
could accept url
as a function that resolves to URL value.
Could you please look into it? I'd be happy to contribute if you need any help.
Hi there,
I'm trying to use @angular-extensions/elements in my project but not able to see anything.
"@angular/core": "~12.2.0",
"@angular-extensions/elements": "^12.6.0"
Sample page
HTML
<ng-template #error>Loading failed...</ng-template>
<blue-ui *axLazyElement="url; errorTemplate: error;" ></blue-ui>
Component
@Component({
selector: 'app-sample-page',
templateUrl: './sample-page.component.html',
styleUrls: ['./sample-page.component.scss']
})
export class SamplePageComponent implements OnInit {
url = 'http://localhost:4201/main.js'
constructor() { }
ngOnInit(): void {
}
}
AppModule
@NgModule({
schemas:[
CUSTOM_ELEMENTS_SCHEMA
],
declarations: [
AppComponent,
SamplePageComponent
],
imports: [
BrowserModule,
AppRoutingModule,
LazyElementsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Is there something wrong in my example?
Edgar
Hi, brilliant job!
Correct me if I am wrong but I think there is a case the library is not covering.
If we are in one of a micro-apps (angular-elements) loaded in shell app, and we want to load other angular elements dynamically, for example widget shared beetwen micro-apps.
When we import LazyElementsModule in Angular Elements, a new instance of LazyElementsLoaderService will be created without knowledge of already registered items.
It would be great if your library covered such a case.
First off, thank you for this package. It has made working with Elements so much more enjoyable. I'm trying to find a way to work locally without having to build every time. I'm currently setup to create Elements as sub-app's or widgets within a larger Angular project. I was following some of the examples on the ngx-build-plus repo where there are build scripts that concatenate all the js of the element, then copy it into the larger application's assets directory. Then I setup the LazyModuleConfigs to point the tag to the corresponding location in the assets folder. This works perfectly. I can work on a change in the Element, then build, then run the main app on Localhost and see if the change functions as it should. However I can't figure out how to have the element running on say localhost:4201, and the main app on 4200, and have the main app point to the localhost:4201 url for the element. This live-reload option would make development of the Element much more fluid. On the corresponding blog post there was a proxy config mentioned, but I can't seem to get that to work either. Any help would be appreciated.
Hi There,
This is more of a doubt rather an issue.
Does the lib support loading of a element which is built using differential build? If yes, is there an example which we can refer to ?
My use case is below
There are multiple angular elements being served from different hosts.
Another app(main) which consumes these elements.
All of them are using same version of libs.
I used externals in all the paces including main app so that the additional scripts file and polyfills would be served from main.
From the elements just included the main bundle file.
It all works fine until I use second element from second bundle.
Once I load the second bundle it errors out with the title and would not load it. Stack trace is as below. Any help to resolve this issue would be appreciated.
Not sure if this is something to do with ngx-build-plus
my externals config is as below
module.exports = {
output: {
jsonpFunction: 'wpJsonpTimeline****'
},
"externals": {
"rxjs": "rxjs",
"@angular/core": "ng.core",
"@angular/common": "ng.common",
"@angular/common/http": "ng.common.http",
"@angular/platform-browser": "ng.platformBrowser",
"@angular/platform-browser-dynamic": "ng.platformBrowserDynamic",
"@angular/compiler": "ng.compiler",
"@angular/elements": "ng.elements",
"@angular/router": "ng.router",
"@angular/forms": "ng.forms"
}
}
Currently, the application fails with the following error when using the module configuration:
ERROR TypeError: Cannot read property 'replace' of undefined
The following code produces the error:
const lazyElementConfig: LazyElementModuleOptions = {
elementConfigs: [
{ tag: 'ba-layout', url: 'http://localhost:4000' }
]
};
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
LazyElementsModule.forRoot(lazyElementConfig)
],
bootstrap: [
AppComponent
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule {}
In AppComponent:
@Component({
selector: 'app-root',
template: `
<ba-layout *axLazyElement>
</ba-layout>
`
})
export class AppComponent {}
I checked the source code and it seems that the directive doesn't look up the config on Angular 7.x branch. Could you please fix it? Or I could submit a PR myself.
how to notify component that element is loaded?
The motivation of this feature is providing a generic way for sharing the state of the registry of loaded web elements across web elements/micro-apps.
The idea is simple, starting from the point we have the main app (aka shell-UI) which is already using angular-extensions/elements
, we should be able to enable that feature via a module configuration flag.
Once this flag is enabled, the main module of this extension will create a web element (root-axLazyElement
) that can be used instead of the directive or the current axLazyElement
component.
Then even a lazy-loaded web components/micro-apps could be benefited from the existing state in the root-axLazyElement
element created by the main app.
During the root-axLazyElement
generation process, we could check if that component is already there or not in order to prevent creating another instance of the root element.
When using @angular/cli to create WebComponents one ends up with at least 2 files for each WebComponent: main.js and styles.js.
But the elementConfig only supports a single URL per element. Sure, I can concatenate the files builded into a single file, this works for production, but not when I want to debug the app locally via ng serve
:(
<ax-lazy-element *axLazyElementDynamic="elementName, url: elementUrl; module: true;"
text2="{{elementText}}"
(send)="onSendReceived($event)"
(navigate)="onNavigate($event)">
i am trying to pass component property : elementText to the custom element.
i can pass strings : text2="my text"
but cannot manage to pass the "elementText" variable.
i've tried:
[text2]="elementText"
text2="{{elementText}}"
but my custom component gets 'null' as the value.
using *axLazyElement the input variables gets passed correctly to the same custom element i've used in the question above.
i've read a similar problem with #50
i've tried the 10-alpha version, still not working. with disabling ivy - not working.
then i've checked again, and it seems that the value was not available during the
connectedCallback event in the web-component. only afterwards.
so i've wrapped the code inside my connectedCallback function with setTimeout and now it works.
Once we have the ElementConfig
's support added, we need to support preloading all web components, even before they are shown in the browser using service
If you make multiple calls to LazyElementsModule.forFeature(options),
... you will only get the last configuration and lose references to other configs.
In LazyElementModule constructor:
if (elementConfigsMultiProvider && elementConfigsMultiProvider.length) {
const lastAddedConfigs =
elementConfigsMultiProvider[elementConfigsMultiProvider.length - 1];
lazyElementsLoaderService.addConfigs(lastAddedConfigs);
}
This should be:
const configs = [].concat.apply([], elementConfigsMultiProvider);
lazyElementsLoaderService.addConfigs(configs);
Hello
good I wanted to see if it is possible to have a project with angular with version 7 and 7 of angular-extensions / elements and make web components of with a project with angular 11 and 11 of angular-extensions / elements
hi,
i am using *axLazyElementDynamic to lazy load dynamic component.
very similar to the dynamic demo in the docs. the configuration is an Array retrieved from the server.
the problem i am facing:
i need to grab a hold on the created element in my class, in order to set some attributed, and register to event emitters.
i've tried using ViewChildren, but cannot get a reference to the element. i've tried various lifecycle hooks (oninit, aftercontentini, afterviewinit) but the viewchildren variable is always undefined.
you're help is appriciated.
I have an angular app which has two apps and one shell app.
Micro app : home and aboutus
Shell app : cz-app
In shell app I have one page (contactus) where I have a drop-down with two values (home and aboutus). Now I want to load an element just below drop-down based on selection value.
I tried to use axLazyElementDynamic and updated configuration on valueChange, but it didn't work.
I tried manually triggering change detection by "this.cdr.detectChanges()". It didn't help me.
Here is my github repo.
Could anyone please check given repo.
Note - both microapps are working fine on separate route.
Angular v 8.6.0
@angular-extensions/elements v 8.6.0
I noticed this when registering the element alongside other html content in the App Component. The entire content is replaced by the loaded element, not just the dom element with the *axLazyElement directive.
I moved the *axLazyElement into a feature module/component, and still noticed that the entire app content was replaced with the loaded element.
I should note that I'm using the module configuration method, instead of the directive Input.
We have a use case similar to the one outlined here: #5
We have a container that knows which features the logged in user has and will send back an array of modules said user has access to. We then loop over these items and render them on the page.
There seems to be a race condition or zone issue (??) with the dynamic directive when trying to render out multiple web components on to the page. What seems to happen is that it'll render out only the last web component multiple times. The source looks suspect as well:
Here is a stackblitz that demonstrates the issue: https://stackblitz.com/edit/axlazy-in-ngfor
FYI, stackblitz seems to hotload components and the CustomElementRegistry will not get wiped out on update so if you edit any of the code it'll complain. Workaround is to just refresh the entire page circa 2003.
You can also modify the existing view to have some type of event handler outside of the ngFor
that will render out the second element but it seems that if these elements are rendered in an ngFor
they are not rendering appropriately.
I have a shell application that loads all the Angular Elements using your library.
On my last update, I figured out cache problems, so the version of the elements was the previous.
In order to solve the problem I had to empty the browser cache.
I know that the cache is managed using the ETag of the file so how can check what's happening?
<element-setPassword id="element-set-password" *axLazyElement="elementUrl" usernamevalue="subham"> --> working
There is an error 404 with service worker. Navigation is impossible.
I have compiled a couple of Angular web elements and am trying to load them dynamically via the ax-lazy-element component like so:
<ax-lazy-element *axLazyElementDynamic="tag, url: url; module: true; errorTemplate: error" [(node)]="node">
</ax-lazy-element>
<ng-template #error>Loading of {{url}} failed...</ng-template>
In the component, I have
public url = 'projects/elements/dist/components/type/item.js';
public tag = 'oyl-type-item'
Just before the error message I am getting a warning
sockjs.js:2999 WebSocket connection to 'ws://localhost:8100/sockjs-node/983/5jt2rk1u/websocket' failed: WebSocket is closed before the connection is established
followed by the error
angular-extensions-elements.js:210 GET http://localhost:8100/projects/elements/dist/components/type/item.js net::ERR_ABORTED 404 (Not Found)
I can do an import with the very same path, aka
const module = await import('projects/elements/dist/components/type/item.js');
and all is good.
Does the localhost:8100 that is apparently added by the ax-lazy-element component change things here?
However, when I pass the very same URL as a variable to import() as in
path = 'projects/elements/dist/components/type/item.js';
import(path)
,
I get the error
Warnings while compiling ... Critical dependency: the request of a dependency is an expression
Which is why I looked for an alternative in the first place and gave your library a spin. I'm just mentioning it because maybe those things are connected?
Hi There,
My use case is as below.
User will drop the component on UI.
We then load angular element as web component at run time via axLazyElementDynamic directive.
We will then initialise the component through typescript in the parent app.
we used a wrapper class in the parent app to load the actual web component considering we need the reference to be able to access public properties.
Though we use the wrapper, the reference is limited to the wrapper but not to the actual component loaded dynamically.
Any insights on how we would be able to access public properties of the dynamically loaded web element using below?
<ax-lazy-element *axLazyElementDynamic="'comp-selector', url: url;">
where the comp-selector is the actual component
Hi,
is there a possibility to get more details about the error which occurred while loading the script?
Especially the HTTP Status Code + message would be interesting.
(In our case we want to decide between missing js and auth problems)
In the code it looks like that there is just a hook if we could successfully load the script file.
Cheers,
Patrick
It more of a suggestion than a issue. We have a scenario where we have grouped multiple web components in a single file. But while specifying the respective file url in the elementConfig, its working only if we add multiple entries for the each component with the same file url.
const plugins: LazyElementModuleOptions = {
elementConfigs:[
{ tag: component1', url: 'assets/component-file.js'},
{ tag: 'component2', url: 'assets/component-file.js'},
{ tag: 'component3', url: 'assets/component-file.js'},
]
}
If a solution exists for the above, please let me know.
If solution doesn't exists, my suggestions would be:
{ tag: 'component-*', url: 'assets/component-file.js'}
<component-one tag-attr *axLazyElement></component-one>
{ attribute-tag: 'tag-attr', url: 'assets/component-file.js'}
LazyElementModuleOptions
with defaultURL
defaultURL
When I load elements from different sources and let's say one source is a bundle of 10 web components and another one is a bundle of one web component I could save some configuration by having a default URL.
If the tag to load is not referenced in elementConfigs
it automatically falls back to the configured default URL.
This could save in the above-mentioned example 10 lines of configuration.
app.module.ts
const options: LazyElementModuleOptions = {
elementConfigs: [
{ tag: 'elements-one', url: 'https://your-org.com/elements/many-elements.js' },
{ tag: 'elements-two', url: 'https://your-org.com/elements/many-elements.js' },
{ tag: 'elements-three', url: 'https://your-org.com/elements/many-elements.js' },
{ tag: 'spacial-element', url: 'https://your-org.com/elements/spacial-element.js' }
]
};
@NgModule({
...
imports: [ LazyElementsModule.forFeature(options)]
})
...
app.component.ts
@Component({
selector: 'your-org-feature',
template: `
<element-one *axLazyElement></element-one>
<element-two *axLazyElement></element-two>
<element-three *axLazyElement></element-three>
<special-element *axLazyElement></special-element>
`
})
export class FeatureComponent {}
app.module.ts
const options: LazyElementModuleOptions = {
defaultURL: 'https://your-org.com/elements/many-elements.js',
elementConfigs: [
{ tag: 'spacial-element', url: 'https://your-org.com/elements/spacial-element.js' }
]
};
@NgModule({
...
imports: [ LazyElementsModule.forFeature(options)]
})
...
app.component.ts
@Component({
selector: 'your-org-feature',
template: `
<element-one *axLazyElement></element-one>
<element-two *axLazyElement></element-two>
<element-three *axLazyElement></element-three>
<special-element *axLazyElement></special-element>
`
})
export class FeatureComponent {}
Hi, is there any possibility to add multiple URL's for one package?
For example in dev env, I want to use the package from source A and in test/prod env from source B.
I have created an example at https://stackblitz.com/edit/angular-extensions-elements-loading?file=src/app/app.component.html
If the element I am trying to reference is not included in the specified URL, I would expect an error message (as I get when the URL itself is bad), but I get the loading indicator.
Hi There,
Here is our use case, we are using gridster2 and axLazyLoad combination for our implementation.
We want to implement the undo functionality.
As part of this we wanted to take advantage of already rendered elements by keeping in an array and embedding the same back on undo considering the time it takes for re rendering the whole element.
However, somehow the content of the lazy loaded element is becoming empty.
Any help to resolve this issue is appreciated.
As the title says, following will lead to an error...
Its something about the internal defineInjectable
...
Would be great to add FAQ section which would explain how to fix that error ( by installing @angular-extensions/elements@^7.0.0 )
Hello everybody,
i have a problem with "multiple different dynamic elements I would like to load 2 web components. The second compnent always uses the js-file of the first component. Therefore the error 'ust-frontend' has already been defined as a custom element. I have built the web components according to the following pattern.
I hope someone can help me.
Thanks
<< ----------------------------------->>
web component
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { Router } from '@angular/router';
import { Location} from '@angular/common';
import { createCustomElement } from '@angular/elements';
import { AppComponent } from './app.component';
import { EcbrateComponent } from './component/ecbrate/ecbrate.component';
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent,
EcbrateComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule
],
providers: [],
entryComponents: [AppComponent]
})
export class AppModule {
constructor(private injector: Injector, private router: Router, private location: Location ) {
const appElement = createCustomElement(AppComponent, {
injector: this.injector
});
console.log('define ecb-frontend');
customElements.define('ecb-frontend', appElement);
console.log('defined ecb-frontend');
console.log(this.location);
this.router.navigateByUrl(this.location.path(true));
console.log(this.router);
this.location.subscribe(data => {
console.log(data);
this.router.navigateByUrl(data.url);
});
}
// tslint:disable-next-line: typedef
ngDoBootstrap() {}
}
<<---------------------------------------------------->>
lazy-element component
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { url } from 'inspector';
@component({
selector: 'app-lazy-element2',
template: <ng-container *ngFor="let c of dynamicConfigs"> {{c.url}} <ax-lazy-element *axLazyElementDynamic= "c.tag, url: c.url; module: true" raised> </ax-lazy-element> </ng-container>
})
export class LazyElement2Component implements OnInit {
elementUrl = '';
elementTag = '';
onDestroy: any;
dynamicConfigs = [];
constructor(readonly activatedRoute: ActivatedRoute) {
/*
this.onDestroy = this.activatedRoute;
// tslint:disable-next-line: deprecation
let componantName = '';
this.onDestroy.url.forEach( item => {
item.forEach( pathItem => {
console.log(pathItem.path);
componantName = pathItem.path;
});
});
this.elementTag = '';
this.elementUrl = 'http://localhost:4201/component/' + componantName + '/' + componantName + '.js';
console.log(this.elementUrl);
this.elementTag = componantName;
*/
this.dynamicConfigs = [
{url: 'http://localhost:4201/component/ust-frontend/ust-frontend.js', tag: 'ust-frontend'},
{url: 'http://localhost:4201/component/ecb-frontend/ecb-frontend.js', tag: 'ecb-frontend'}
];
}
ngOnInit(): void {}
// tslint:disable-next-line: use-lifecycle-interface
ngOnDestroy() {
// this.onDestroy.unsubscribe();
}
}
<< --------------------------- >>
app.module
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { LazyElementsModule } from '@angular-extensions/elements';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/header/header.component';
import { HomeComponent } from './components/home/home.component';
import { DynamicLayoutComponent } from './components/dynamic-layout/dynamic-layout.component';
import { LazyElementComponent } from './components/lazy-element/lazy-element.component';
import { MainLayoutComponent } from './components/dynamic-layout/main-layout.component';
import { LoginComponent } from './components/login/login.component';
import { ReactiveFormsModule } from '@angular/forms';
import { LazyElement2Component } from './components/lazy-element2/lazy-element2.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [
AppComponent,
HeaderComponent,
HomeComponent,
DynamicLayoutComponent,
LazyElementComponent,
LazyElement2Component,
MainLayoutComponent,
LoginComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
LazyElementsModule,
CommonModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
I'm creating a POC in an Nx monorepo using @angular-architects/ddd and have an issue where using a web-component inside one the libs is not working as expected. I have one component loaded in at the global level that works as expected. However, the second component inside the feature is not rendering. I can see the script tag being added to the DOM and there are no console errors but the component itself is not rendering. This is all that is added to the DOM where the component should be
<!--bindings={
"ng-reflect-url": "http://localhost:3333/api/publ"
}-->
Further Testing: I added a loading template and the loading template is showing as expected but is never disappearing. I know the URL is serving the component and that the JS for the component is valid as well.
Hi guys!
I've been trying to load 2 of my angular elements using the library. You can find them here and here
Here is the repo for the main app: click
I have a 3rd project setup like this:
const options: LazyElementModuleOptions = {
elementConfigs: [
{ tag: 'edo-button', url: 'https://kmanev073.github.io/EdoButton/dist/main-es2015.js' },
{ tag: 'edo-input', url: 'https://kmanev073.github.io/EdoInput/dist/main-es2015.js' }
]
};
Then I use my components as:
<edo-button *axLazyElement
></edo-button>
<edo-input *axLazyElement
></edo-input>
<edo-button *axLazyElement
></edo-button>
It all works and you just need to add some extra scripts to your index.html:
<script src="https://kmanev073.github.io/EdoButton/dist/polyfills-es2015.js"></script>
<script src="https://kmanev073.github.io/EdoButton/dist/scripts.js" defer></script>
<script src="https://kmanev073.github.io/EdoButton/dist/polyfill-webcomp.js" defer></script>
Now the problem...
The EdoButton and the EdoInput both have Inputs and Outputs. When I try to use them like this:
<edo-button *axLazyElement
[edoValue]="'-'"
(edoClick)="onMinusClick($event)"
></edo-button>
<edo-input *axLazyElement
[edoValue]="value"
(edoChange)="onInputChange($event)"
></edo-input>
<edo-button *axLazyElement
[edoValue]="'+'"
(edoClick)="onPlusClick($event)"
></edo-button>
I get an error saying:
ERROR in src/app/app.component.html(2,3): Property 'edoValue' does not exist on type 'HTMLElement'.
src/app/app.component.html(7,3): Property 'edoValue' does not exist on type 'HTMLElement'.
src/app/app.component.html(12,3): Property 'edoValue' does not exist on type 'HTMLElement'.
Any ideas on how to enable inputs and outputs?
Getting this error while using external url to load js file “angular-extensions-elements.js:184 Cross-Origin Read Blocking (CORB) blocked cross-origin response“
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.