2017-06-20 66 views
17

我創建角圖書館ngx-wig),我想提供使用插件以擴展其功能的能力。角:爲第三方包(庫)創建的插件

在Angular中聲明插件的最佳位置是什麼? (可能類似myLibModule.forRoot(..))以及什麼類型的實例應該是插件本身?

solved same issueAngularJs只是通過添加模塊的每個中,我通過使用主模塊的configProvider寄存器插件插件。不太喜歡這個解決方案,因爲插件自己註冊,但它應該是使用庫的應用程序的責任。

UPDATE:相關問題在github上打開here

+0

這似乎有點不清楚。你想提供一個類似於服務的API嗎? –

+0

它取決於插件。其中一些可以用新按鈕擴展工具欄 –

+0

好問題。我在模塊化音樂製作系統中遇到類似的問題,並且解決方案是每個插件的「表面部分」必須堅持定義插件組件的接口,例如,關鍵字 - 關於插件的元數據,例如名稱,鍵類等,然後插件的內部部分通過放置在方法上的裝飾器鉤子(例如'@ nodeDidActivate','@ nodeStateDidChange'等等)工作。 )。該系統使用React作爲其UI層,但它不應該在ng中有所不同。 –

回答

2

我認爲你可以提供用戶使用組件作爲插件。這個組件必須擴展你抽象的基本插件組件。

例如clear-styles插件可能看起來像

@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); 
    } 
} 

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是抽象基類,您的圖書館提供:

export abstract class Ng2WigPluginComponent { 
    execCommand: Function; 
    editMode: boolean; 
    content: string; 

    editModelChange: EventEmitter<boolean> = new EventEmitter(); 
    contentChange: EventEmitter<string> = new EventEmitter(); 
} 

讓用戶可以輕鬆使用在基類中聲明屬性。

要註冊這樣的插件,我們可以使用您提到的forRoot方法。對於您需要

1)配置你的資料庫模塊就像如下:

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是您的全局庫令牌識別庫內提供的插件

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是角全球令牌能夠加載插件在AppModule模塊的聲明陣列動態

2)聲明NwClearStylesButtonComponent

3)將其傳遞給Ng2WigModule.forRoot方法

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

然後主,你的任務將是利用ComponentFactoryResolverViewContainerRef動態生成組件(見下文plunker ng2wig-plugin.directive.ts

Plunker Example

+0

謝謝你,你的答案很棒!我以前沒有提供賞金來激勵他人分享他們的答案 –