@jamesbenrobb/dynamic-routes-ngx
v0.0.8
Published
Angular specific application shell for dynamic routing
Downloads
16
Readme
Dynamic Routes Ngx
What.
An Angular implementation of @jamesbenrobb/dynamic-routes
.
Note - Only the highlighted area in Fig 1. relates to this library.
The surrounding UI in the demo is part of a separate library (@jamesbenrobb/app-shell
) and is used in this instance to:
- Facilitate user route changes
- Demonstrate the composable nature of this library
Fig 1. Only the highlighted area relates to this library and is the default content displayed when using the component
Why.
Whilst creating Documentor (which required dynamic/configurable routes) it became apparent that it would be useful to abstract and decouple the underlying implementation/behaviour to use in other apps.
What not.
A replacement for complex routing.
How.
- Install
- Define route config json
- Add providers
- Add component
- Interact with router
- Extending for your own use
Install
npm i @jamesbenrobb/dynamic-routes-ngx@latest
Define route config json
{
"routes": [{
"path": "/",
"redirectTo": "one"
}, {
"path": "one",
"content": {
"someProp": "someValue"
}
}, {
"path": "two",
"label": "2",
"content": {
"someOtherProp": "someOtherValue"
},
"children": [{
"path": "two-first-child",
"content": {}
}]
}, {
"path": "three",
"content": {
"someOtherProp": "someOtherValue"
},
"children": [{
"path": "three-first-child",
"content": {}
}, {
"path": "three-second-child",
"content": {},
"children": [{
"path": "three-second-child-first-child",
"content": {}
}]
}]
}]
}
Add providers
import {ApplicationConfig} from '@angular/core';
import {getJBRDRAppProviders} from "@jamesbenrobb/dynamic-routes-ngx";
export const appConfig: ApplicationConfig = {
providers: [
getJBRDRAppProviders(
'assets/route-config.json'
)
]
};
Add component
import { Component } from '@angular/core';
import {AppContentContainerComponent} from "@jamesbenrobb/dynamic-routes-ngx";
@Component({
selector: 'app-root',
standalone: true,
imports: [
AppContentContainerComponent
],
template: `
<jbr-dra-app-content-container>
</jbr-dra-app-content-container>
`,
styleUrl: './app.component.scss'
})
export class AppComponent {}
Interact with router
The RouteManager
can be injected and exposes the following API:
readonly currentRouteNodes$: Observable<RouteNode<T>[]>;
readonly urlChange$: Observable<string>;
get routes(): RouteNode<T>[];
navigateByUrl(path: string): void;
navigateByNode(node: RouteNode<T>): void;
Extending for your own use.
Provider options
export type JBRDRAppProvidersOptions<T extends ContentNodeContentType> = {
appName?: string,
getAllChildNodes?: getAllChildNodes<T>
contentComponentType?: string
}
Add your own content component
Create a component that implements ContentLoaderComponentIO
import {Component, Output} from "@angular/core";
import {ContentLoaderComponentIO} from "@jamesbenrobb/dynamic-routes-app";
@Component({
selector: 'my-content-component',
templateUrl: '...',
styleUrls: ['...'],
standalone: true
})
export class MyContentComponent implements ContentLoaderComponentIO<YourContentType> {
@Input() routeNodes?: RouteNode<YourContentType>[] | undefined
@Input() currentNode?: RouteNode<YourContentType> | undefined
@Input() currentContent?: YourContentType | undefined
@Output() routeSelected = new EventEmitter<RouteNode<>>(); // this is optional
}
Register the component with the ComponentLoaderMapService
(see details on registering components here) and add the provider to your app
import {Provider} from "@angular/core";
import {ComponentLoaderMapService} from "@jamesbenrobb/ui";
const provider: Provider = {
provide: ComponentLoaderMapService,
useValue: {
'my-content-component': {
import: () => import('./my-content.component'),
componentName: 'MyContentComponent'
}
},
multi: true
}
Supply the registered name of you content component to getJBRDRAppProviders
import {ApplicationConfig} from '@angular/core';
import {getJBRDRAppProviders} from "@jamesbenrobb/dynamic-routes-ngx";
export const appConfig: ApplicationConfig = {
providers: [
getJBRDRAppProviders(
'assets/route-config.json',
{
appName: 'My app name',
contentComponentType: 'my-content-component'
}
)
]
};