Angulaire: Création de plugins pour les paquets tiers (bibliothèques)

J'ai créé Angular Library ( ngx-wig ) et j'aimerais pouvoir étendre sa fonctionnalité à l'aide de plugins .

Quel serait le meilleur endroit pour déclarer un plugin dans Angular? ( Peut-être quelque chose comme myLibModule.forRoot(..) ) et quel type d'instance devrait être le plugin lui-même?

J'ai résolu le même problème pour AngularJs en ajoutant un module pour chaque plugin dans lequel j'inscrit un plugin en utilisant configProvider du module principal. J'aime vraiment cette solution car le plugin s'inscrit, mais il devrait être responsable des applications où la bibliothèque est utilisée.

MISE À JOUR : la question connexe est ouverte sur github ici .

Je pense que vous pouvez fournir aux utilisateurs l'utilisation du composant en tant que plug-in. Ce composant doit étendre votre composant de plugin de base abstraite.

Par exemple clear-styles plugin clear-styles pourrait ressembler

 @Component({ selector: `nw-clear-styles-button`, template: ` <button (click)="clearStyles($event)" [disabled]="editMode || disabled" class="nw-button clear-styles" title="Clear Styles"> Clear Styles </button>` }) export class NwClearStylesButtonComponent extends Ng2WigPluginComponent { constructor() { super(); } clearStyles() { const div = document.createElement('div'); div.innerHTML = this.content; this.contentChange.emit(div.textContent); } } 

Plugin de format

 @Component({ selector: `nw-formats-button`, template: ` <select class="nw-select" [(ngModel)]="format" (ngModelChange)="execCommand('formatblock', format.value)" [disabled]="editMode || disabled"> <option *ngFor="let format of formats" [ngValue]="format">{{ format.name }}</option> </select> ` }) export class NwFormatButtonComponent extends Ng2WigPluginComponent { formats = [ {name: 'Normal text', value: '<p>'}, {name: 'Header 1', value: '<h1>'}, {name: 'Header 2', value: '<h2>'}, {name: 'Header 3', value: '<h3>'} ]; format = this.formats[0]; constructor() { super(); } } 

Ng2WigPluginComponent est une classe de base abstraite fournie par votre bibliothèque:

 export abstract class Ng2WigPluginComponent { execCommand: Function; editMode: boolean; content: string; editModelChange: EventEmitter<boolean> = new EventEmitter(); contentChange: EventEmitter<string> = new EventEmitter(); } 

Ainsi, les utilisateurs peuvent facilement utiliser les propriétés déclarées dans les classes de base.

Pour enregistrer ces plugins que nous pouvons utiliser mentionnés par vous forRoot méthode forRoot . Pour cela, vous devez

1) configurez votre module de bibliothèque comme suit:

Ng2wig.module.ts

 @NgModule({ ... }) export class Ng2WigModule { static forRoot(entryComponents: CustomButton[]) { return { ngModule: Ng2WigModule, providers: [ Ng2WigToolbarService, {provide: NG_WIG_CUSTOM_BUTTONS, useValue: entryComponents}, {provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: entryComponents}, ] }; } } 

  • NG_WIG_CUSTOM_BUTTONS est votre jeton de bibliothèque global pour reconnaître les plugins fournis dans la bibliothèque

Ng2wig-toolbar.service.ts

 @Injectable() export class Ng2WigToolbarService { constructor(@Optional() @Inject(NG_WIG_CUSTOM_BUTTONS) customButtons: CustomButton[]) { if (customButtons) { customButtons.forEach(plugin => this.addCustomButton(plugin.pluginName, plugin.component)); } } 
  • ANALYZE_FOR_ENTRY_COMPONENTS est un jeton global angulaire pour pouvoir charger des plugins dynamiquement

2) Déclarez NwClearStylesButtonComponent dans le tableau des déclarations de votre module AppModule

3) Passer à la méthode Ng2WigModule.forRoot

 Ng2WigModule.forRoot([ { pluginName: 'clear-styles', component: NwClearStylesButtonComponent }, { pluginName: 'format', component: NwFormatButtonComponent } ]) 

Et puis, la tâche principale sera de générer dynamiquement votre composant en utilisant ComponentFactoryResolver et ViewContainerRef (voir ng2wig-plugin.directive.ts dans plunker ci-dessous)

Exemple de plongeur