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 ComponentFactoryResolver
và ViewContainerRef
(xem ng2wig-plugin.directive.ts
trong plunker bên dưới)
Plunker Example
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? –
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 –
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. –