2017-06-20 15 views
17

Tôi tạo ra Thư viện góc (ngx-wig) và tôi muốn cung cấp một khả năng để mở rộng chức năng của nó bằng cách sử dụng plugins.góc: Tạo plugin cho các gói bên thứ 3 (thư viện)

Điều gì sẽ là nơi tốt nhất để khai báo plugin trong Angular? (có thể giống như myLibModule.forRoot(..)) và loại cá thể nào sẽ là chính plugin?

I solved same issue cho AngularJs chỉ bằng cách thêm mô-đun cho mỗi plugin mà tôi đăng ký plugin bằng cách sử dụng configProvider của mô đun chính. Không thực sự thích giải pháp này bởi vì plugin đăng ký chính nó, nhưng nó phải là trách nhiệm của các ứng dụng mà thư viện được sử dụng.

CẬP NHẬT: sự cố liên quan được mở trên github here.

+0

Có vẻ như một chút không rõ ràng. Bạn có muốn cung cấp một API như dịch vụ không? –

+0

tùy thuộc vào plugin. một số người trong số họ có thể mở rộng thanh công cụ bằng nút mới –

+0

Câu hỏi hay. Tôi đã phải đối mặt với một vấn đề tương tự trong hệ thống sản xuất nhạc mô-đun và giải pháp là "phần bề mặt" của mỗi plugin phải tuân theo giao diện xác định assembly _plugin, ví dụ: key-metadata về plugin, chẳng hạn như name, key-classes, vv, và sau đó các phần bên trong của plugin tự hoạt động thông qua các decorator-hooks được đặt trên các phương thức (chẳng hạn như '@ nodeDidActivate',' @ nodeStateDidChange', v.v.). Hệ thống này sử dụng React làm lớp giao diện người dùng của nó, nhưng nó không phải là khác nhau trong ng. –

Trả lời

2

Tôi nghĩ bạn có thể cung cấp cho người dùng sử dụng thành phần làm plugin. Thành phần này phải mở rộng cho bạn thành phần cơ sở plugin trừu tượng.

Ví dụ clear-styles plugin có thể trông giống như

@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 Plugin

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

nơi Ng2WigPluginComponent là lớp cơ sở trừu tượng được cung cấp bởi thư viện của bạn:

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

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

Vì vậy, người dùng có thể dễ dàng sử dụng khai báo trong lớp cơ sở tính chất.

Để đăng ký các plugin như vậy, chúng tôi có thể sử dụng phương pháp forRoot được đề cập. Cho rằng bạn cần phải

1) cấu hình bạn mô-đun thư viện như sau:

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}, 
     ] 
    }; 
    } 
} 

nơi

  • NG_WIG_CUSTOM_BUTTONS là thư viện toàn cầu của bạn mã thông báo để nhận dạng các plugin được cung cấp bên trong thư viện

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 là góc dấu hiệu toàn cầu để có thể tải plugin động

2) Khai NwClearStylesButtonComponent trong tờ khai hàng loạt các mô-đun AppModule bạn

3) Chuyển nó đến phương thức Ng2WigModule.forRoot

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

Và sau đó chính bạn nhiệm vụ sẽ tự động tạo ra thành phần của bạn bằng cách sử dụng ComponentFactoryResolverViewContainerRef (xem ng2wig-plugin.directive.ts trong plunker bên dưới)

Plunker Example

+0

cảm ơn bạn, câu trả lời của bạn thật tuyệt vời! Tôi đã không cung cấp tiền thưởng trước đây để động viên người khác chia sẻ câu trả lời của họ –

Các vấn đề liên quan