Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dan-harris/ngx-loadable-component
Provides a simple interface for dynamic, lazy loadable components
https://github.com/dan-harris/ngx-loadable-component
angular angular-cli typescript typescript-library
Last synced: 2 months ago
JSON representation
Provides a simple interface for dynamic, lazy loadable components
- Host: GitHub
- URL: https://github.com/dan-harris/ngx-loadable-component
- Owner: dan-harris
- License: mit
- Created: 2018-07-04T07:35:41.000Z (over 6 years ago)
- Default Branch: develop
- Last Pushed: 2019-02-24T01:06:32.000Z (almost 6 years ago)
- Last Synced: 2024-10-01T15:05:56.435Z (3 months ago)
- Topics: angular, angular-cli, typescript, typescript-library
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/ngx-loadable-component
- Size: 304 KB
- Stars: 11
- Watchers: 3
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![ngx-loadable-component](https://github.com/dan-harris/ngx-loadable-component/raw/master/logo.png)
Dynamically lazy load & code-split your Angular components.
![](https://badgen.net/npm/v/ngx-loadable-component) ![](https://badgen.net/bundlephobia/minzip/ngx-loadable-component) ![](https://img.shields.io/badge/angular-v6%20%7C%20v7-red.svg) ![](https://badgen.net/github/license/dan-harris/ngx-loadable-component) ![](https://img.shields.io/badge/awesome-yes%20%F0%9F%91%8D-bb0073.svg)
(Supports Angular 6+)
Core functionality derived _heavily_ from [dynamically loading components with angular-cli](https://blog.angularindepth.com/dynamically-loading-components-with-angular-cli-92a3c69bcd28)
## Easily 💤 lazy load & ⚡ code-split, components in 🅰 Angular
🚧 no mucking around with seperate build processes
💤 lazy load components
🆓 free code splitting via Angular
⚡ [demo](https://ngx-loadable-component-app-chfnxlwwxx.now.sh/)
🤓 ingenious core pattern thought up by _[actual smart people](https://blog.angularindepth.com/dynamically-loading-components-with-angular-cli-92a3c69bcd28)_
👌 created for the use case of seperating large single components (such as wysiwg editors, charts .etc) from the rest of your app code.
# Installation
Install via npm;
```
npm i ngx-loadable-component
```_\* unfortunately, only an aot build angular setup will work correctly within the **loadable component** setup 🤷 ️ .. an example of how this is setup can be seen within the base directory of this repo(app demo)_
# Setup
Create a component you wish to dynamically load... e.g. **loadable component**
_upside-down-face-emoji.component.ts_
```typescript
@Component({
selector: 'app-upside-down-face-emoji'
...
})
export class UpsideDownFaceEmojiComponent { }
```_\* its important that this component does not use `OnPush` changeDetection as this will interfere with the **loadable component** setup_
Then create a module for the **loadable component**:
_upside-down-face-emoji.module.ts_
```typescript
import { LoadableComponentModule } from 'ngx-loadable-component';import { UpsideDownFaceEmojiComponent } from './upside-down-face-emoji.component';
@NgModule({
imports: [
// register as loadable component
LoadableComponentModule.forChild(UpsideDownFaceEmojiComponent)
],
declarations: [UpsideDownFaceEmojiComponent]
})
export class UpsideDownFaceEmojiComponentModule {}
```Create a **manifest** file which lists all your **loadable components**:
_app-loadable.manifests.ts_
```typescript
import { LoadableManifest } from 'ngx-loadable-component';export enum LoadableComponentIds {
UPSIDE_DOWN_FACE = 'UpsideDownFaceEmojiComponent'
}export const appLoadableManifests: Array = [
{
// used to retrieve the loadable component later
componentId: LoadableComponentIds.UPSIDE_DOWN_FACE,
// must be a unique value within the app...
// but apart from that only used by angular when loading component
path: `loadable-${LoadableComponentIds.UPSIDE_DOWN_FACE}`,
// relative path to component module
loadChildren: './components/upside-down-face-emoji/upside-down-face-emoji.module#UpsideDownFaceEmojiComponentModule'
}
];
```Add the **loadable component manifest** & **loadable component module** to root app module:
_app.module.ts_
```typescript
import { LoadableComponentModule } from 'ngx-loadable-component';// loadable components manifest
import { appLoadableManifests } from './app-loadable.manifests';@NgModule({
declarations: [
...
],
imports: [
...
// components to load as seperate async
LoadableComponentModule.forRoot(appLoadableManifests)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
```Be sure to import the **loadable component module** into any feature modules you use it in:
_my-feature.module.ts_
```typescript
import { LoadableComponentModule } from 'ngx-loadable-component';@NgModule({
declarations: [
...
],
imports: [
...
LoadableComponentModule.forFeature()
]
})
export class MyFeatureModule { }
```# Usage (basic)
Add a **loadable component** where needed:
_app.component.html_
```html
```_app.component.ts_
```typescript
import { LoadableComponentIds } from '../../app-loadable.manifests';@Component({ ... })
export class AppComponent {
// loadable component ids
UPSIDE_DOWN_FACE_COMPONENT_ID: string = LoadableComponentIds.UPSIDE_DOWN_FACE;// flags to load components
// setting this to 'true' will cause the loadable component
// to load the specified component id
loadUpsideDownFaceComponent: boolean = false;
}
```# Usage (with Inputs/Outputs)
If our **loadable component** has inputs/outputs - like so:
_upside-down-face-emoji.component.html_
```html
🙃
{{ text }}
```_upside-down-face-emoji.component.ts_
```typescript
export class UpsideDownFaceEmojiComponent {
@Input() text: string = 'upside down';@Output() clicked: EventEmitter = new EventEmitter();
constructor() {}
onClick(): void {
this.clicked.emit(this.text);
}
}
```We then create a model representing the inputs/outputs (for some typing goodness 💯):
_upside-down-face-emoji.inputs.model.ts_
```typescript
import { LoadableComponentInputs } from 'ngx-loadable-component';export interface UpsideDownFaceEmojiComponentInputs extends LoadableComponentInputs {
text: string;
}
```_upside-down-face-emoji.outputs.model.ts_
```typescript
import { LoadableComponentOutputs } from 'ngx-loadable-component';export interface UpsideDownFaceEmojiComponentOutputs extends LoadableComponentOutputs {
clicked: Function;
}
```And add our inputs/outputs to the **loadable component** wherever its used:
_app.component.html_
```html
```_app.component.ts_
```typescript
import { LoadableComponentIds } from '../../app-loadable.manifests';
import { UpsideDownFaceEmojiComponentInputs } from '../../components/upside-down-face-emoji/models/upside-down-face-emoji.inputs.model';
import { UpsideDownFaceEmojiComponentOutputs } from '../../components/upside-down-face-emoji/models/upside-down-face-emoji.outputs.model';@Component({ ... })
export class AppComponent {
// loadable component ids
UPSIDE_DOWN_FACE_COMPONENT_ID: string = LoadableComponentIds.UPSIDE_DOWN_FACE;// flags to load components
// setting this to 'true' will cause the loadable component
// to load the specified component id
loadUpsideDownFaceComponent: boolean = false;// inputs for loadable component
get upsideDownFaceInputs(): UpsideDownFaceEmojiComponentInputs {
return {
text: 'not upside down'
}
}// outputs for loadable component
get upsideDownFaceOutputs(): UpsideDownFaceEmojiComponentOutputs {
return {
clicked: (text: string) => this.onClickedUpsideDownFace(text)
}
}onClickedUpsideDownFace(text: string): void {
console.log('🖱', text);
}
}
```And voila! we now have input/output binding 👌.
_\* note that the inputs in the parent component (of the loadable component - e.g. `upsideDownFaceInputs()`) have to be within a getter or function for change detection to apply correctly_# Usage (add custom css classes)
Custom css classes can be passed via the _loadable component_ `componentCssClasses` input.
These will be added to the host element of the provided loadable component. e.g._app.component.html_
```html
...
```_app.component.ts_
```typescript
@Component({ ... })
export class AppComponent {
...
// custom css classes
customCssClasses: Array = ['my-custom--class--1', 'my-custom--class--2']
...
}
```# Author
🤔 created by Dan Harris
👨💻 website: [danharris.io](https://danharris.io)
🐤 twitter: [@danharris_io](http://twitter.com/danharris_io)
☕ made with love and late nights
🤷 this package works well for my use case... no guarantees made to its general use
# Odds & Ends
👀 MIT License
💖 if you've read this far... thanks for the star
😎 title font courtesy of the awesome [lazer84 font](http://sunrise-digital.net/lazer84/)
😡 please send all abusive letters via handwritten note to [this address](https://www.youtube.com/watch?v=dQw4w9WgXcQ)
📫 all constructive feedback welcome.