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 --saveConsuming library
You can import library in any Angular application by running:
$ npm i fusion-view --saveCreate 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-permissionshttps://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 ©
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago