Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
При создании модификаций для SharePoint вы могли использовать объектную модель JavaScript (JSOM) для связи с SharePoint. Это больше не рекомендуемый путь (см. Рекомендации далее в этой статье). Однако по-прежнему существуют допустимые случаи использования API JSOM, например миграция кода.
Чтобы использовать модель JSOM в компоненте SharePoint Framework, необходимо включить ее в проект. Раньше это не требовалось, так как она уже была доступной на страницах SharePoint для использования. В SharePoint Framework ее необходимо загрузить непосредственно в компонент.
Сослаться на модель JSOM в SharePoint Framework можно двумя способами:
- декларативно — через конфигурацию;
- принудительно — через код.
У каждого из этих подходов есть свои преимущества и недостатки, каждый из которых важно понимать.
Создание проекта
С помощью консоли создайте папку для проекта:
md react-sharepointlists
Перейдите в папку проекта:
cd react-sharepointlists
В папке проекта запустите генератор Yeoman для SharePoint Framework, чтобы сформировать шаблон проекта на платформе SharePoint Framework:
yo @microsoft/sharepoint
При появлении запроса введите следующие значения (выберите вариант по умолчанию для всех запросов, не перечисленных ниже).
- Как называется решение?: react-sharepointlists
- Какой тип клиентского компонента нужно создать?: WebPart
- Как называется веб-часть?: Списки SharePoint
- Какой шаблон вы хотите использовать?: React
Откройте папку проекта в редакторе кода. В инструкциях и на снимках экрана в этой статье упоминается Visual Studio Code, но вы можете использовать любой редактор.
Чтобы открыть каталог в Visual Studio Code, введите в консоли следующую команду:
code .
Добавление декларативных ссылок на JSOM
Регистрация API JSOM SharePoint в качестве внешних скриптов
Ссылаясь на JSOM декларативно, сначала необходимо зарегистрировать API JSOM SharePoint в качестве внешних скриптов в проекте SharePoint Framework.
Откройте в редакторе кода файл ./config/config.json и добавьте следующий код в раздел
externals
:{ // ... "externals": { "sp-init": { "path": "https://contoso.sharepoint.com/_layouts/15/init.js", "globalName": "$_global_init" }, "microsoft-ajax": { "path": "https://contoso.sharepoint.com/_layouts/15/MicrosoftAjax.js", "globalName": "Sys", "globalDependencies": [ "sp-init" ] }, "sp-runtime": { "path": "https://contoso.sharepoint.com/_layouts/15/SP.Runtime.js", "globalName": "SP", "globalDependencies": [ "microsoft-ajax" ] }, "sharepoint": { "path": "https://contoso.sharepoint.com/_layouts/15/SP.js", "globalName": "SP", "globalDependencies": [ "sp-runtime" ] } } // ... }
Каждая запись указывает на один из скриптов, которые вместе позволяют использовать JSOM SharePoint в компоненте SPFx. Эти скрипты не распространяются как модули. Поэтому для каждой записи о регистрации необходимо указать URL-адрес (свойство
path
) и имя (свойствоglobalName
), используемые скриптом. Чтобы эти скрипты загружались в правильном порядке, зависимости между ними необходимо указать с помощью свойстваglobalDependencies
.В зависимости от того, какие функции JSOM используются, могут потребоваться дополнительные скрипты (например, sp.taxonomy.js).
Установка определений типов TypeScript для JSOM SharePoint
Следующий шаг — установка и настройка описаний типов TypeScript для JSOM SharePoint. Это позволяет пользоваться функциями, обеспечивающими безопасность типов TypeScript при работе с JSOM SharePoint.
С помощью консоли выполните в каталоге проекта следующую команду:
npm install @types/microsoft-ajax @types/sharepoint --save-dev
Модель JSOM SharePoint не распространяется как модуль, поэтому ее нельзя импортировать в код напрямую. Вместо этого необходимо глобально зарегистрировать ее глобальные описания типов TypeScript.
Откройте в редакторе кода файл ./tsconfig.json, а затем в свойстве
types
(после записиwebpack-env
) добавьте ссылки наmicrosoft-ajax
иsharepoint
:{ "compilerOptions": { // ... "types": [ "es6-promise", "es6-collections", "webpack-env", "microsoft-ajax", "sharepoint" ] } }
Создание ссылок на скрипты JSOM SharePoint в компоненте React
Чтобы можно было загружать библиотеки JSOM SharePoint в компоненте SPFx, необходимо ссылаться на них в коде компонента. В этом примере добавляются ссылки в компоненте React, где JSOM SharePoint используется для связи с SharePoint.
Откройте в редакторе кода файл ./src/webparts/sharePointLists/components/SharePointLists.tsx. После последнего оператора import
добавьте следующий код:
require('sp-init');
require('microsoft-ajax');
require('sp-runtime');
require('sharepoint');
Эти имена соответствуют ранее добавленным внешним ссылкам. SharePoint Framework загрузит эти скрипты из указанных URL-адресов.
Чтобы продемонстрировать связь с SharePoint с помощью SharePoint JSOM, извлеките и выведите заголовки всех списков SharePoint на текущем сайте.
Добавление свойства siteUrl
для компонента React
Чтобы подключиться к SharePoint, компонент React должен знать URL-адрес текущего сайта. Этот URL-адрес доступен в родительской веб-части, и его можно передавать компоненту через его свойства.
В редакторе кода откройте файл ./src/webparts/sharePointLists/components/ISharePointListsProps.ts и добавьте
siteUrl
свойство вISharePointListsProps
интерфейс:export interface ISharePointListsProps { description: string; siteUrl: string; }
Чтобы передать компоненту URL-адрес текущего сайта, откройте файл ./src/webparts/sharePointLists/SharePointListsWebPart.ts и измените метод
render()
следующим образом:export default class SharePointListsWebPart extends BaseClientSideWebPart<ISharePointListsWebPartProps> { public render(): void { const element: React.ReactElement<ISharePointListsProps > = React.createElement( SharePointLists, { description: this.properties.description, siteUrl: this.context.pageContext.web.absoluteUrl } ); ReactDom.render(element, this.domElement); } // ... }
Определение состояния компонента React
Компонент React загружает данные из SharePoint и показывает их пользователю. Текущее состояние компонента React моделируется с помощью добавляемого интерфейса состояний.
С помощью редактора кода создайте в папке ./src/webparts/sharePointLists/components файл ISharePointListsState.ts и вставьте следующий текст:
export interface ISharePointListsState {
listTitles: string[];
loadingLists: boolean;
error: string;
}
Добавление состояния компонента React
Определив интерфейс, описывающий форму состояния компонента, необходимо сделать так, чтобы компонент React использовал этот интерфейс состояния.
Откройте в редакторе кода файл ./src/webparts/sharePointLists/components/SharePointLists.tsx. Под имеющимися операторами
import
добавьте следующее:import { ISharePointListsState } from './ISharePointListsState';
Измените подпись класса
SharePointLists
следующим образом:export default class SharePointLists extends React.Component<ISharePointListsProps, ISharePointListsState> { // ... }
В классе
SharePointLists
добавьте конструктор со значением состояния по умолчанию:export default class SharePointLists extends React.Component<ISharePointListsProps, ISharePointListsState> { constructor(props?: ISharePointListsProps, context?: any) { super(); this.state = { listTitles: [], loadingLists: false, error: null }; } // ... }
Загрузка сведений о списках SharePoint с текущего сайта с помощью JSOM
Пример клиентской веб-части, используемый в этой статье, загружает сведения из списков SharePoint на текущем сайте после нажатия кнопки.
Откройте в редакторе кода файл ./src/webparts/sharePointLists/components/SharePointLists.tsx. В классе
SharePointLists
добавьте методgetListsTitles()
:export default class SharePointLists extends React.Component<ISharePointListsProps, ISharePointListsState> { constructor(props?: ISharePointListsProps, context?: any) { super(); this.state = { listTitles: [], loadingLists: false, error: null }; this.getListsTitles = this.getListsTitles.bind(this); } // ... private getListsTitles(): void { } }
Чтобы обеспечить правильное определение области метода, привяжите его к веб-части в конструкторе. Используйте JSOM SharePoint в методе
getListsTitles()
, чтобы загрузить названия списков SharePoint на текущем сайте:export default class SharePointLists extends React.Component<ISharePointListsProps, ISharePointListsState> { // ... private getListsTitles(): void { this.setState({ loadingLists: true, listTitles: [], error: null }); const context: SP.ClientContext = new SP.ClientContext(this.props.siteUrl); const lists: SP.ListCollection = context.get_web().get_lists(); context.load(lists, 'Include(Title)'); context.executeQueryAsync((sender: any, args: SP.ClientRequestSucceededEventArgs): void => { const listEnumerator: IEnumerator<SP.List> = lists.getEnumerator(); const titles: string[] = []; while (listEnumerator.moveNext()) { const list: SP.List = listEnumerator.get_current(); titles.push(list.get_title()); } this.setState((prevState: ISharePointListsState, props: ISharePointListsProps): ISharePointListsState => { prevState.listTitles = titles; prevState.loadingLists = false; return prevState; }); }, (sender: any, args: SP.ClientRequestFailedEventArgs): void => { this.setState({ loadingLists: false, listTitles: [], error: args.get_message() }); }); } }
Для начала сбросьте состояние компонента, чтобы сообщить пользователю, что компонент загружает сведения из SharePoint. Используя URL-адрес текущего сайта, передаваемый компоненту через его свойства, мы создаем новый экземпляр контекста SharePoint. Используя JSOM SharePoint, мы загружаем списки с нынешнего сайта. Чтобы увеличить скорость выполнения запроса, мы указываем, что должно загружаться только свойство Title
.
Затем мы выполняем запрос, вызывая метод executeQueryAsync()
и передавая две функции обратного вызова. После этого мы просматриваем коллекцию полученных списков, сохраняем их названия в массиве и обновляем состояние компонента.
Отображение названий списков SharePoint на текущем сайте
После загрузки названий списков SharePoint на текущем сайте остается только показать их в компоненте.
Откройте в редакторе кода файл ./src/webparts/sharePointLists/components/SharePointLists.tsx и обновите метод
render()
:export default class SharePointLists extends React.Component<ISharePointListsProps, ISharePointListsState> { // ... public render(): React.ReactElement<ISharePointListsProps> { const titles: JSX.Element[] = this.state.listTitles.map((listTitle: string, index: number, listTitles: string[]): JSX.Element => { return <li key={index}>{listTitle}</li>; }); return ( <div className={styles.sharePointLists}> <div className={styles.container}> <div className={`ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}`}> <div className="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1"> <span className="ms-font-xl ms-fontColor-white">Welcome to SharePoint!</span> <p className="ms-font-l ms-fontColor-white">Customize SharePoint experiences using web parts.</p> <p className="ms-font-l ms-fontColor-white">{escape(this.props.description)}</p> <a className={styles.button} onClick={this.getListsTitles} role="button"> <span className={styles.label}>Get lists titles</span> </a><br /> {this.state.loadingLists && <span>Loading lists...</span>} {this.state.error && <span>An error has occurred while loading lists: {this.state.error}</span>} {this.state.error === null && titles && <ul> {titles} </ul>} </div> </div> </div> </div> ); } // ... }
На этом этапе вы можете добавить веб-часть на страницу и просмотреть заголовки списков SharePoint на текущем сайте. Чтобы убедиться, что проект работает правильно, выполните следующую команду в консоли:
gulp serve --nobrowser
Так как вы используете JSOM SharePoint для связи с SharePoint, веб-часть необходимо протестировать с помощью размещенной версии SharePoint Workbench (именно поэтому указывается параметр
--nobrowser
— он предотвращает автоматическую загрузку локальной версии Workbench).Декларативные ссылки на скрипты JSOM SharePoint (как на внешние скрипты) удобно использовать, и они делают код более удобочитаемым. Недостаток этого способа заключается в том, что необходимо указывать абсолютные URL-адреса источников, из которых загружаются скрипты JSOM SharePoint. Если вы используете отдельные клиенты SharePoint для разработки, тестирования и производства, эти URL-адреса необходимо адаптировать для разных сред. В таких случаях советуем ссылаться на JSOM принудительно, используя SPComponentLoader для загрузки скриптов в коде компонента SPFx.
Добавление принудительных ссылок на JSOM
Для загрузки библиотек JavaScript в проектах SharePoint Framework также можно использовать вспомогательный класс SharePoint Framework SPComponentLoader
, предназначенный для загрузки скриптов и других ресурсов. В отличие от декларативной загрузки скриптов, при использовании SPComponentLoader
можно применять URL-адреса, заданные относительно сервера. Это удобно, если для разных стадий разработки используются разные клиенты SharePoint.
Эта часть руководства основана на коде, созданном ранее в разделе "Добавление декларативных ссылок на JSOM".
Установка @microsoft/sp-loader модуля
SPComponentLoader
объявляется в отдельном модуле @microsoft/sp-loader , который должен быть установлен в проекте.
С помощью консоли выполните в каталоге проекта следующую команду:
npm install @microsoft/sp-loader --save
Удаление декларативных ссылок
Если вы добавили декларативные ссылки в разделах выше, их необходимо удалить.
Удалите существующие ссылки на внешние скрипты. Откройте в редакторе кода файл ./config/config.json и удалите из свойства
externals
все записи:{ "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json", "version": "2.0", "bundles": { "share-point-lists-web-part": { "components": [ { "entrypoint": "./lib/webparts/sharePointLists/SharePointListsWebPart.js", "manifest": "./src/webparts/sharePointLists/SharePointListsWebPart.manifest.json" } ] } }, "externals": {}, "localizedResources": { "SharePointListsWebPartStrings": "lib/webparts/sharePointLists/loc/{locale}.js" } }
Так как скрипты JSOM SharePoint больше не регистрируются как внешние скрипты, на них невозможно ссылаться в коде напрямую.
Откройте в редакторе кода файл ./src/webparts/sharePointLists/components/SharePointLists.tsx и удалите операторы
require()
, указывающие на разные скрипты JSOM SharePoint.
Задержка загрузки данных до загрузки сценариев JSOM SharePoint
Основная функциональность клиентской веб-части, которую мы создадим в этом руководстве, зависит от SharePoint JSOM. Загрузка этих скриптов может занять несколько минут (в зависимости от ряда факторов). При создании компонентов SPFx, использующих JSOM SharePoint, следует учитывать это. При добавлении на страницу веб-часть должна сообщать пользователю о загрузке необходимых компонентов и ясно показывать, когда она готова к использованию.
Для этого необходимо расширить состояние компонента React с помощью дополнительного свойства для отслеживания состояния загрузки скриптов JSOM.
Откройте в редакторе кода файл ./src/webparts/sharePointLists/components/ISharePointListsState.ts и вставьте следующий код:
export interface ISharePointListsState { listTitles: string[]; loadingLists: boolean; error: string; loadingScripts: boolean; }
Добавьте новое свойство к определениям состояний в компоненте React. Откройте в редакторе кода файл ./src/webparts/sharePointLists/components/SharePointLists.tsx. Обновите конструктор, вставив следующий код:
export default class SharePointLists extends React.Component<ISharePointListsProps, ISharePointListsState> { constructor(props?: ISharePointListsProps, context?: any) { super(); this.state = { listTitles: [], loadingLists: false, error: null, loadingScripts: true }; this.getListsTitles = this.getListsTitles.bind(this); } // ... }
В том же файле замените код метода
getListsTitles()
на следующий:export default class SharePointLists extends React.Component<ISharePointListsProps, ISharePointListsState> { // ... private getListsTitles(): void { this.setState({ loadingLists: true, listTitles: [], error: null, loadingScripts: false }); const context: SP.ClientContext = new SP.ClientContext(this.props.siteUrl); const lists: SP.ListCollection = context.get_web().get_lists(); context.load(lists, 'Include(Title)'); context.executeQueryAsync((sender: any, args: SP.ClientRequestSucceededEventArgs): void => { const listEnumerator: IEnumerator<SP.List> = lists.getEnumerator(); const titles: string[] = []; while (listEnumerator.moveNext()) { const list: SP.List = listEnumerator.get_current(); titles.push(list.get_title()); } this.setState((prevState: ISharePointListsState, props: ISharePointListsProps): ISharePointListsState => { prevState.listTitles = titles; prevState.loadingLists = false; return prevState; }); }, (sender: any, args: SP.ClientRequestFailedEventArgs): void => { this.setState({ loadingLists: false, listTitles: [], error: args.get_message(), loadingScripts: false }); }); } }
Чтобы пользователь видел состояние загрузки скриптов JSOM SharePoint, замените код метода
render()
на следующий:export default class SharePointLists extends React.Component<ISharePointListsProps, ISharePointListsState> { // ... public render(): React.ReactElement<ISharePointListsProps> { const titles: JSX.Element[] = this.state.listTitles.map((listTitle: string, index: number, listTitles: string[]): JSX.Element => { return <li key={index}>{listTitle}</li>; }); return ( <div className={styles.sharePointLists}> <div className={styles.container}> {this.state.loadingScripts && <div className="ms-Grid" style={{ color: "#666", backgroundColor: "#f4f4f4", padding: "80px 0", alignItems: "center", boxAlign: "center" }}> <div className="ms-Grid-row" style={{ color: "#333" }}> <div className="ms-Grid-col ms-u-hiddenSm ms-u-md3"></div> <div className="ms-Grid-col ms-u-sm12 ms-u-md6" style={{ height: "100%", whiteSpace: "nowrap", textAlign: "center" }}> <i className="ms-fontSize-su ms-Icon ms-Icon--CustomList" style={{ display: "inline-block", verticalAlign: "middle", whiteSpace: "normal" }}></i><span className="ms-fontWeight-light ms-fontSize-xxl" style={{ paddingLeft: "20px", display: "inline-block", verticalAlign: "middle", whiteSpace: "normal" }}>SharePoint lists</span> </div> <div className="ms-Grid-col ms-u-hiddenSm ms-u-md3"></div> </div> <div className="ms-Grid-row" style={{ width: "65%", verticalAlign: "middle", margin: "0 auto", textAlign: "center" }}> <span style={{ color: "#666", fontSize: "17px", display: "inline-block", margin: "24px 0", fontWeight: 100 }}>Loading SharePoint JSOM scripts...</span> </div> <div className="ms-Grid-row"></div> </div>} {this.state.loadingScripts === false && <div className={`ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}`}> <div className="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1"> <span className="ms-font-xl ms-fontColor-white">Welcome to SharePoint!</span> <p className="ms-font-l ms-fontColor-white">Customize SharePoint experiences using web parts.</p> <p className="ms-font-l ms-fontColor-white">{escape(this.props.description)}</p> <a className={styles.button} onClick={this.getListsTitles} role="button"> <span className={styles.label}>Get lists titles</span> </a><br /> {this.state.loadingLists && <span>Loading lists...</span>} {this.state.error && <span>An error has occurred while loading lists: {this.state.error}</span>} {this.state.error === null && titles && <ul> {titles} </ul>} </div> </div> } </div> </div> ); } // ... }
Когда состояние компонента React указывает на загрузку скриптов JSOM SharePoint, отображается заполнитель. После загрузки скриптов в веб-части отображается стандартное содержимое с кнопкой, позволяющей пользователям загрузить информацию о списках SharePoint на текущем сайте.
Загрузка сценариев JSOM SharePoint с помощью SPComponentLoader
Компоненты SPFx должны загружать сценарии JSOM SharePoint только один раз. В этом примере, учитывая, что веб-часть состоит из одного компонента React, лучше всего загружать сценарии JSOM SharePoint внутри метода компонента componentDidMount()
React, который выполняется только один раз после создания экземпляра компонента.
Откройте в редакторе кода файл ./src/webparts/sharePointLists/components/SharePointLists.tsx. Добавьте в начале файла оператор
import
, ссылающийся на классSPComponentLoader
. Добавьте методcomponentDidMount()
в классSharePointLists
:import { SPComponentLoader } from '@microsoft/sp-loader'; export default class SharePointLists extends React.Component<ISharePointListsProps, ISharePointListsState> { // ... public componentDidMount(): void { SPComponentLoader.loadScript('/_layouts/15/init.js', { globalExportsName: '$_global_init' }) .then((): Promise<{}> => { return SPComponentLoader.loadScript('/_layouts/15/MicrosoftAjax.js', { globalExportsName: 'Sys' }); }) .then((): Promise<{}> => { return SPComponentLoader.loadScript('/_layouts/15/SP.Runtime.js', { globalExportsName: 'SP' }); }) .then((): Promise<{}> => { return SPComponentLoader.loadScript('/_layouts/15/SP.js', { globalExportsName: 'SP' }); }) .then((): void => { this.setState((prevState: ISharePointListsState, props: ISharePointListsProps): ISharePointListsState => { prevState.loadingScripts = false; return prevState; }); }); } // ... }
Используя цепочку обещаний, мы загружаем различные скрипты, которые вместе позволяют использовать JSOM SharePoint в компоненте SharePoint Framework. Благодаря классу
SPComponentLoader
вы можете использовать URL-адреса, заданные относительно сервера, которые загружают скрипты из текущего клиента SharePoint. После загрузки всех скриптов вы обновляете состояние компонента React, подтверждая, что все необходимые компоненты загружены, а веб-часть готова к использованию.Убедитесь, что веб-часть работает надлежащим образом, выполнив в консоли следующую команду:
gulp serve --nobrowser
Как и раньше, в веб-части должны появиться названия списков SharePoint на текущем сайте.
Использование класса SPComponentLoader
требует дополнительной работы, но позволяет указывать URL-адреса, заданные относительно сервера. Это удобно, когда для разработки, тестирования и производства используются разные клиенты.
Замечания
В прошлом при создании клиентских модификаций на платформах SharePoint вы могли использовать JSOM SharePoint для связи с SharePoint. В настоящее время рекомендуем использовать REST API SharePoint напрямую или через основную библиотеку PnP JavaScript.
Когда была представлена JSOM для SharePoint, это был первый шаг к поддержке клиентских решений в SharePoint. Однако он больше не поддерживается активно и может не предоставлять доступ ко всем возможностям, доступным через REST API. Кроме того, независимо от того, используете ли rest API SharePoint напрямую или через библиотеку PnP JavaScript Core, вы можете использовать обещания, которые значительно упрощают написание асинхронного кода (распространенная проблема при использовании JSOM).
Несмотря на то что в редких случаях SharePoint JSOM все еще может предоставлять доступ к данным и методам, не поддерживаемым в REST API SharePoint, по мере возможности рекомендуется использовать REST API.
Если у вас есть существующие настройки с помощью SharePoint JSOM и вы планируете перенести их на SharePoint Framework, в этой статье должны содержаться необходимые сведения об использовании JSOM SharePoint в решениях SharePoint Framework. Однако в долгосрочной перспективе следует рассмотреть возможность изменения способа взаимодействия с SharePoint на использование REST API SharePoint напрямую или с помощью основной библиотеки JavaScript PnP.