elements icon indicating copy to clipboard operation
elements copied to clipboard

Suggestion Extending `LazyElementModuleOptions`

Open BioPhoton opened this issue 6 years ago • 6 comments

Suggestion Extending to extend LazyElementModuleOptions with defaultURL

Suggestion To Implement a new option 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.

Actual Behaviour

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 {}

Suggested Behaviour

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 {}

BioPhoton avatar Sep 23 '19 23:09 BioPhoton

@BioPhoton welcome bro!

tomastrajan avatar Sep 24 '19 05:09 tomastrajan

@BioPhoton so this is about single bundle having multiple elements, wouldn't in that case make more sense to have something like { tag: ['tag1', 'tag2', tag3], url: 'https://your-org.com/elements/many-elements.js' } ? That way is explicit, and single config. I can see disadvantage that this has to be adjusted always when a new tag is added to the bundle.

When you first described feature to me the way I understood it then was more like

'defaultURL: 'https://your-org.com/elements/'

And then if tag is <some-element> the final url would be 'https://your-org.com/elements/some-element.js', with theoretical option to pass in (tag: string) => url: string converter if the final url should look different.

Also in theory, if you pre-load your bundle "many-elements" bundle you could just use element tag as is without *axLazyElement... The main point being, once bundle is loaded other tags will just work...

This concept is used in one of the examples (<ion-item> with nested <ion-label> and <ion-datetime>)in demo page with ionic, it only specifies wrapper element because when children are rendered bundle was already loaded...

What are your thoughts... I think it can still make sense to have this, just thinking about all the possible trade-offs, thanks for the request!

tomastrajan avatar Sep 24 '19 06:09 tomastrajan

... something like { tag: ['tag1', 'tag2', tag3], url: 'https://your-org.com/elements/many-elements.js' } This is also a thing that would save lines. Would be really cool to have this also in the lib.

But I mean I can directly use it in the template and have to maintain the tag name only in the template if there would be a defaultUrl.

BioPhoton avatar Sep 25 '19 00:09 BioPhoton

Would this not work? having *axLazyElement only on special-element

@Component({
  selector: 'your-org-feature',
  template: `
    <element-one></element-one>
    <element-two></element-two>
    <element-three></element-three>
    <special-element *axLazyElement></special-element>
  `
})
export class FeatureComponent {}

mohammedzamakhan avatar Sep 27 '19 12:09 mohammedzamakhan

So as soon as i put it in the config it preloads? I thought I can trigger it with putting the directive there. 🤔

BioPhoton avatar Sep 30 '19 00:09 BioPhoton

@BioPhoton it depends... Have to add more examples in the demo to show it off.

Currently, there are 2 ways to preload, one is to use service which is fully in control of the DEV, eg preload in route guard, preload on click, whatever... Even though triggering preloading is just that, we're currently not returning promise or anything (which we should @mohammedzamakhan ) so you don't really know if stuff was fully preloaded yet...

Similar to that, specifying preload: true in the config will trigger preloading of that element once the module is executed. This can be startup for eager modules or later when the lazy module is loaded for the first time.

If we had an guarantee that the element was fully preloaded before it appears in the template, then we could just use <some-element> without any directive.

With directive we have a guarantee that the element was loaded, and was loaded only once because the directive would get pending promise from the registry if the element loading was already triggered but not yet resolved (eg by preloading)

tomastrajan avatar Sep 30 '19 06:09 tomastrajan