Kusi's Knowledgebase¶
OnPrem SPFx¶
SPFx Introduction Manual¶
gulp serve with localizaion¶
gulp dist for SP2016/19¶
gulp dist replace the steps:
Install gulp-sequence
edit file gulpfile.js
'use strict';
if (process.argv.indexOf('dist') !== -1){
process.argv.push('--ship');
}
const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
const gulpSequence = require('gulp-sequence');
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
gulp.task('dist', gulpSequence('clean', 'bundle', 'package-solution'));
build.initialize(gulp);
Get ListItem by ID¶
this.props.spHttpClient.get(
encodeURI(`${this.props.siteurl}/_api/web/lists/getbytitle('${listName}')/items(${itemId})?$select=Id,Title`),
SPHttpClient.configurations.v1)
.then(res => res.json())
.then(res => {
...
});
Get ListItem by filter¶
this.props.spHttpClient.get(
encodeURI(`${this.props.siteurl}/_api/web/lists/getbytitle('${listName}')/items(${itemId})?$filter=Title eq '...'&$select=Id,Title`),
SPHttpClient.configurations.v1)
.then(res => res.json())
.then(res => {
...
});
CAML Query¶
this._webPartContext.spHttpClient.post(
`${this.props.siteUrl}/_api/web/lists/GetByTitle('${this.listName}')/GetItems`,
SPHttpClient.configurations.v1,
{
headers: {
'odata-version': '3.0',
'content-type': 'application/json;odata=verbose',
'accept': 'application/json;odata=verbose'
},
body: JSON.stringify(
{
'query': {
'__metadata': { 'type': 'SP.CamlQuery' },
'ViewXml': `<View><Query><Where>${viewXml}</Where><OrderBy><FieldRef Name='Title' Ascending='False' /></OrderBy></Query></View>`
}
}),
method: 'POST'
})
.then(res => res.json())
.then(res => {
...
});;
Create ListItem¶
this.props.spHttpClient.post(
`${this.props.siteurl}/_api/web/lists/GetByTitle('${listName}')/items`,
SPHttpClient.configurations.v1, {
headers: {
'odata-version': '3.0',
'Accept': 'application/json;odata=verbose',
'Content-Type': 'application/json;odata=verbose'
},
body: JSON.stringify(
{
'__metadata': {
'type': `SP.Data.${listName}ListItem`
},
'Title': ...
}
),
method: 'POST'
}).then(r => {
...
});
Update ListItem¶
this.props.spHttpClient.post(
`${this.props.siteurl}/_api/web/lists/GetByTitle('${listName}')/items(${itemId})`,
SPHttpClient.configurations.v1, {
headers: {
'odata-version': '3.0',
'Accept': 'application/json;odata=verbose',
'Content-Type': 'application/json;odata=verbose',
'IF-MATCH': '*',
'X-HTTP-Method': 'MERGE'
},
body: JSON.stringify(
{
'__metadata': {
'type': `SP.Data.${listName}ListItem`
},
'Title': ...
}
),
method: 'POST'
}).then(res => {
...
});
Delete ListItem¶
this.props.spHttpClient.post(
`${this.props.siteurl}/_api/web/lists/GetByTitle('${listName}')/items(${itemId})`,
SPHttpClient.configurations.v1, {
headers: {
'odata-version': '3.0',
'Accept': 'application/json;odata=nometadata',
'Content-Type': 'application/json;odata=verbose',
'IF-MATCH': '*',
'X-HTTP-Method': 'DELETE'
},
method: 'POST'
}).then(r => {
...
});
Search¶
const postData: string = JSON.stringify({
'request': {
'__metadata': {
'type': 'Microsoft.Office.Server.Search.REST.SearchRequest'
},
'Querytext': `ContentTypeId:"${contentTypeId}*" ${queryText ? `"${queryText}" ` : ''}`
}
});
SPHttpClient.post(
`${this.props.siteurl}/_api/search/postquery`,
SPHttpClient.configurations.v1, {
headers: {
'odata-version': '3.0',
'Accept': 'application/json;odata=verbose',
'Content-Type': 'application/json;odata=verbose',
'Content-Length': postData.length.toString()
},
body: postData,
method: 'POST'
}
)
.then(response => response.json())
.then(response => {
if (!(response)) {
return;
}
resolve(response.d.postquery.PrimaryQueryResult.RelevantResults.Table.Rows.results);
});
Send Mail¶
this._webPartContext.spHttpClient.get(
this._webAbsoluteUrl + '/_api/web/currentuser',
SPHttpClient.configurations.v1
)
.then(res => res.json())
.then(currentuser => {
this._webPartContext.spHttpClient.post(
this._webAbsoluteUrl + "/_api/SP.Utilities.Utility.SendEmail",
SPHttpClient.configurations.v1,
{
headers: {
'content-type': 'application/json;odata=verbose',
'accept': 'application/json;odata=verbose'
},
body: JSON.stringify({
'properties': {
'To': [eMail],
'CC': currentuser.Email,
'Subject': '...',
'Body': '<div>' +
...
'</div>'
}
}),
method: 'POST'
}).then(resp => { resolve(true); });
})
.catch(err => {
console.log(err);
resolve(false);
});
RxJsEventEmitter¶
To communicate between 2 WebParts you can use the RxJSEventEmitter
Receiver WebPart¶
import { RxJsEventEmitter } from './RxJsEventEmitter';
export default class ... {
private readonly eventEmitter: RxJsEventEmitter = RxJsEventEmitter.getInstance();
...
private onClick(...): void {
...
this.eventEmitter.emit('timShareData', data);
}
}
Sender WebPart¶
import { RxJsEventEmitter } from './RxJsEventEmitter';
export default class ... {
private readonly eventEmitter: RxJsEventEmitter = RxJsEventEmitter.getInstance();
public constructor(...) {
this.eventEmitter.on('timShareData', this.receiveData.bind(this));
...
}
...
protected receiveData(data: IEventData): void {
...
}
}
RxJsEventEmitter.ts¶
import { Subject } from 'rx-lite';
export class RxJsEventEmitter {
public subjects: Object;
// tslint:disable-next-line: no-any
public readonly hasOwnProp: any = {}.hasOwnProperty;
// tslint:disable:no-string-literal
public static getInstance(): RxJsEventEmitter {
if (!window['RxJsEventEmitter']) {
window['RxJsEventEmitter'] = new RxJsEventEmitter();
}
return window['RxJsEventEmitter'];
}
public emit(name: string, data: Object): void {
const fnName: string = this._createName(name);
if (!this.subjects[fnName]) {
this.subjects[fnName] = new Subject();
}
this.subjects[fnName].onNext(data);
}
public on(name: string, handler: any): void {
const fnName: string = this._createName(name);
if (!this.subjects[fnName]) {
this.subjects[fnName] = new Subject();
}
this.subjects[fnName].subscribe(handler);
}
public off(name: string): void {
const fnName: string = this._createName(name);
if (this.subjects[fnName]) {
this.subjects[fnName].dispose();
delete this.subjects[fnName];
}
}
public dispose(): void {
const subjects: Object = this.subjects;
for (const prop in subjects) {
if (this.hasOwnProp.call(subjects, prop)) {
subjects[prop].dispose();
}
}
this.subjects = {};
}
private constructor() {
this.subjects = {};
}
private _createName(name: string): string {
return `$${name}`;
}
}