fusion-view v0.7.9
fusion-view
Dynamic component composition for your angular (v6, v7) applications (AOT, lazy modules compatible).
Table of contents
Installation
To install this library, run:
$ npm i fusion-view --save
Consuming library
You can import library in any Angular application by running:
$ npm i fusion-view --save
Create a component that is isolated to a module for itself. Ensure then component's class is placed inside the entryComponents field of the module. Ensure the component's module imports all the modules that is required by the component.
// Component
@Component({
selector: 'app-user-card',
templateUrl: './user-card.component.html',
styleUrls: ['./user-card.component.scss']
})
export class UserCardComponent implements OnInit {
@Input() user: User = new User();
}
// Component's Module
@NgModule({
declarations: [UserCardComponent],
entryComponents: [UserCardComponent],
imports: [
CommonModule,
]
})
export class UserCardModule { }
Define the manifest for your dynamic components in a typescript file for eg. component-manifest.ts
import {FusionManifest} from 'fusion-view';
export const COMPONENT_MANIFESTS: FusionManifest[] = [
{
// Unique string that thee uses to locate this component
componentId: 'user-card',
// String selector that is found in the component definition
selector: 'app-user-card',
// Any unique string, this is used internally by the angular router
path: 'user-card',
// The path of the component's module, relative to the app module's location
loadChildren: './users/user-card.module#UserCardModule'
}
];
and then from your Angular AppModule
:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {provideRoutes} from '@angular/router';
import { AppComponent } from './app.component';
// Import your library
import { FusionModule } from 'ngx-permissions';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
// Include the fusion module passing the manifests that was created before
// as a parameter
FusionModule.forRoot(COMPONENT_MANIFESTS),
],
providers: [
// Provide the manifests that was created to the router
provideRoutes(COMPONENT_MANIFESTS)
],
bootstrap: [AppComponent]
})
export class AppModule { }
NB. If you want to specify manifests from multiple files, you can do the following:
CARDS_MANIFESTS and VIEWS_MANIFESTS are variables located in two different files
// For module Import FusionModule.forRoot([ ...CARDS_MANIFESTS, ...VIEWS_MANIFESTS ])
// For providing manifests to angular router provideRoutes( ...CARDS_MANIFESTS, ...VIEWS_MANIFESTS )
###
___
To create a component dynamically, first ensure the FusionModule is imported into the module you are working with.
```typescript
@NgModule({
declarations: [EmployeeListComponent],
entryComponents: [EmployeeListComponent],
imports: [
CommonModule,
FusionModule // FusionModule imported
]
})
export class EmployeesModule { }
We want to create the user-card dynamically inside the EmployeeListComponent. It would look something like this:
user-card.ts
@Component({
selector: 'app-user-card',
templateUrl: './user-card.component.html',
styleUrls: ['./user-card.component.scss']
})
export class EmployeeListComponent implements OnInit {
userList: User[];
}
user-card.html
<div class="user-list">
<div fusion-view
componentId="app-user-card"
*ngFor="let userData of userList;"
[data]="{ user: userData }"></div>
</div>
You can specify inputs of the component by passing it as a property of a object into the data attribute.
Using Permissions
Permissions allow you to determine if a component should be created, based on permissions the user current have. While this library does not provide a built in permission manager, fusion-view can hook into various permission managers that already exists. For this example, we will be using
ngx-permissions
https://github.com/AlexKhymenko/ngx-permissions
Above your AppModule
, we will create the following function:
export function permissionChecker(permissionsService: NgxPermissionsService) {
return (permissions: string[]) => {
return permissionsService.hasPermission(permissions);
};
}
This exported function returns another function, that accepts the permission list of type string array as its parameter.
The return type of this function can be either a boolean
or a Promise<boolean>
which would determine if a component
should be created or not.
Inside the AppModule
, you would need to include the function created above as a provider to the Fusion library.
providers: [
{
provide: FUSION_PERMISSION_CHECKER,
useFactory: permissionChecker,
deps: [NgxPermissionsService]
},
],
Next you would need to update the manifest of the component you want to apply permissions to. Add the property permissions to the manifest, this accepts a string array of the permissions needed to create this component.
export const COMPONENT_MANIFESTS: FusionManifest[] = [
{
componentId: 'user-card',
selector: 'app-user-card',
path: 'user-card',
loadChildren: './users/user-card.module#UserCardModule',
permissions: ['CAN_VIEW_USER']
}
];
If you do not specify the permissions property, or assign an empty array, fusion-view will by default render the component
And that's pretty much it. Once the permission library tells fusion-view that the user has the necessary permissions, the component would be created, otherwise the component would not be created.
Credits
This project was inspired by the following articles https://blog.angularindepth.com/dynamically-loading-components-with-angular-cli-92a3c69bcd28 https://blog.angularindepth.com/here-is-what-you-need-to-know-about-dynamic-components-in-angular-ac1e96167f9e
License
MIT ©
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago