/
KoTemplateSampleWebPart.ts
96 lines (81 loc) · 2.73 KB
/
KoTemplateSampleWebPart.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import * as ko from 'knockout';
import {
BaseClientSideWebPart,
IPropertyPaneSettings,
IWebPartContext,
PropertyPaneTextField
} from '@microsoft/sp-webpart-base';
import * as strings from 'koTemplateSampleStrings';
import KoTemplateSampleViewModel, { IKoTemplateSampleBindingContext } from './KoTemplateSampleViewModel';
import { IKoTemplateSampleWebPartProps } from './IKoTemplateSampleWebPartProps';
let _instance: number = 0;
export default class KoTemplateSampleWebPart extends BaseClientSideWebPart<IKoTemplateSampleWebPartProps> {
private _id: number;
private _componentElement: HTMLElement;
private _koDescription: KnockoutObservable<string> = ko.observable('');
/**
* Shouter is used to communicate between web part and view model.
*/
private _shouter: KnockoutSubscribable<{}> = new ko.subscribable();
public constructor(context: IWebPartContext) {
super(context);
this._id = _instance++;
const tagName: string = `ComponentElement-${this._id}`;
this._componentElement = this._createComponentElement(tagName);
this._registerComponent(tagName);
// When web part description is changed, notify view model to update.
this._koDescription.subscribe((newValue: string) => {
this._shouter.notifySubscribers(newValue, 'description');
});
}
public onInit(): Promise<void> {
const bindings: IKoTemplateSampleBindingContext = {
description: this.properties.description,
shouter: this._shouter
};
ko.applyBindings(bindings, this._componentElement);
return super.onInit();
}
public render(): void {
if (!this.renderedOnce) {
this.domElement.appendChild(this._componentElement);
}
this._koDescription(this.properties.description);
}
private _createComponentElement(tagName: string): HTMLElement {
const componentElement: HTMLElement = document.createElement('div');
componentElement.setAttribute('data-bind', `component: { name: "${tagName}", params: $data }`);
return componentElement;
}
private _registerComponent(tagName: string): void {
ko.components.register(
tagName,
{
viewModel: KoTemplateSampleViewModel,
template: require('./KoTemplateSample.template.html'),
synchronous: false
}
);
}
protected get propertyPaneSettings(): IPropertyPaneSettings {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
})
]
}
]
}
]
};
}
}