Использование заполнителей страниц из настройщика заполнителей (Hello World, часть 2)

Настройщики заполнителей обеспечивают доступ к известным местам на страницах SharePoint, которые можно менять в соответствии с организационными и функциональными требованиями. Например, вы можете создать динамические верхний и нижний колонтитулы, которые отображаются на всех страницах в SharePoint Online.

Эта модель сопоставима с использованием коллекции UserCustomAction в объекте Site или Web для изменения страницы с помощью пользовательского кода JavaScript. Ключевое отличие расширений SharePoint Framework (SPFx) заключается в том, что элементы страницы не будут изменяться при внесении изменений в структуру HTML/DOM в SharePoint Online.

В этой статье описано, как сделать так, чтобы расширение Hello World использовало заполнители страниц.

Вы также можете следовать этому руководству, посмотрев видео на канале YouTube сообщества платформы Microsoft 365 (PnP):

Получение доступа к заполнителям страниц

Расширения настройщика приложений поддерживаются в областях "Сайт", "Веб" и "Список ". Вы можете контролировать место и способ регистрации настройщика заполнителей в клиенте SharePoint.

Примечание.

Регистрация Настройщика приложений на основе XML-кода поддерживается только на уровне веб-сайта или списка. Однако можно активировать настройщик приложений более широко либо с помощью развертывания расширений на уровне клиента , либо путем связывания настройщика приложений UserCustomAction с коллекцией объекта Site .

Когда настройщик заполнителей существует в области и отображается, вы можете использовать следующий метод, чтобы получить доступ к заполнителю.

// Handling the Bottom placeholder
if (!this._bottomPlaceholder) {
  this._bottomPlaceholder =
    this.context.placeholderProvider.tryCreateContent(
      PlaceholderName.Bottom,
      { onDispose: this._onDispose });
...
}

После этого вы полностью контролируете, какие элементы показываются конечному пользователю.

Обратите внимание, что вы запрашиваете известный заполнитель, используя соответствующий известный идентификатор. В этом случае код обращается к нижнему колонтитулу страницы с помощью Bottom параметра в перечислении PlaceholderName .

Добавления элементов HTML для изменения заполнителей

  1. Установите пакет @microsoft/sp-office-ui-fabric-core , чтобы включить импорт из SPFabricCore.scss. Мы будем использовать его для определения стилей отрисовки для наших заполнителей.

    npm install @microsoft/sp-office-ui-fabric-core
    
  2. Создайте файл с именем ./src/extensions/helloWorld/AppCustomizer.module.scss.

  3. Измените файл AppCustomizer.module.scss следующим образом:

    Примечание.

    Это стили, которые используются в выходном HTML-коде для верхнего и нижнего колонтитулов.

    @import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
    
    .app {
      .top {
          height:60px;
          text-align:center;
          line-height:2.5;
          font-weight:bold;
          display: flex;
          align-items: center;
          justify-content: center;
          background-color: $ms-color-themePrimary;
          color: $ms-color-white;
    
      }
    
      .bottom {
          height:40px;
          text-align:center;
          line-height:2.5;
          font-weight:bold;
          display: flex;
          align-items: center;
          justify-content: center;
          background-color: $ms-color-themePrimary;
          color: $ms-color-white;
      }
    }
    
  4. В Visual Studio Code (или предпочитаемой интегрированной среде разработки) откройте ./src/extensions/helloWorld/HelloWorldApplicationCustomizer.ts.

  5. PlaceholderContent Добавьте и PlaceholderName в инструкцию import из @microsoft/sp-application-base, обновив инструкцию import следующим образом:

    import {
      BaseApplicationCustomizer,
      PlaceholderContent,
      PlaceholderName
    } from '@microsoft/sp-application-base';
    

    Кроме того, добавьте следующие операторы импорта после кода импорта strings в начале файла:

    import styles from './AppCustomizer.module.scss';
    import { escape } from '@microsoft/sp-lodash-subset';
    

    Вы будете использовать escape функцию для экранирования свойств настройщика приложений. На следующих этапах вы создадите определения стилей для выходных данных.

    Примечание.

    После вставки в приведенный выше фрагмент кода может появиться сообщение об ошибке при использовании Visual Studio Code. Эти ошибки исчезают после сборки решения при компиляции scss-файла в класс.

  6. В файле HelloWorldApplicationCustomizer.ts обновите IHelloWorldApplicationCustomizerProperties интерфейс, чтобы добавить определенные свойства для колонтитулов, как показано ниже.

    Примечание.

    Если настройщик приложений ClientSideComponentProperties использует входные данные JSON, он десериализуется в BaseExtension.properties объект . Вы можете определить интерфейс для его описания.

    export interface IHelloWorldApplicationCustomizerProperties {
      Top: string;
      Bottom: string;
    }
    
  7. Добавьте в класс следующие частные HelloWorldApplicationCustomizer переменные. В этом случае это могут быть локальные переменные в методе onRender(), но если вы хотите, чтобы они были доступны другим объектам, определите их как частные переменные.

    export default class HelloWorldApplicationCustomizer
      extends BaseApplicationCustomizer<IHelloWorldApplicationCustomizerProperties> {
    
      // These have been added
      private _topPlaceholder: PlaceholderContent | undefined;
      private _bottomPlaceholder: PlaceholderContent | undefined;
    
      // ...
    }
    
  8. Обновите код метода onInit() как показано ниже.

    public onInit(): Promise<void> {
      Log.info(LOG_SOURCE, `Initialized ${strings.Title}`);
    
      // Wait for the placeholders to be created (or handle them being changed) and then
      // render.
      this.context.placeholderProvider.changedEvent.add(this, this._renderPlaceHolders);
    
      return Promise.resolve();
    }
    
  9. Создайте новый частный метод _renderPlaceHolders() со следующим кодом:

    private _renderPlaceHolders(): void {
      console.log("HelloWorldApplicationCustomizer._renderPlaceHolders()");
      console.log(
        "Available placeholders: ",
        this.context.placeholderProvider.placeholderNames
          .map(name => PlaceholderName[name])
          .join(", ")
      );
    
      // Handling the top placeholder
      if (!this._topPlaceholder) {
        this._topPlaceholder = this.context.placeholderProvider.tryCreateContent(
          PlaceholderName.Top,
          { onDispose: this._onDispose }
        );
    
        // The extension should not assume that the expected placeholder is available.
        if (!this._topPlaceholder) {
          console.error("The expected placeholder (Top) was not found.");
          return;
        }
    
        if (this.properties) {
          let topString: string = this.properties.Top;
          if (!topString) {
            topString = "(Top property was not defined.)";
          }
    
          if (this._topPlaceholder.domElement) {
            this._topPlaceholder.domElement.innerHTML = `
            <div class="${styles.app}">
              <div class="${styles.top}">
                <i class="ms-Icon ms-Icon--Info" aria-hidden="true"></i> ${escape(
                  topString
                )}
              </div>
            </div>`;
          }
        }
      }
    
      // Handling the bottom placeholder
      if (!this._bottomPlaceholder) {
        this._bottomPlaceholder = this.context.placeholderProvider.tryCreateContent(
          PlaceholderName.Bottom,
          { onDispose: this._onDispose }
        );
    
        // The extension should not assume that the expected placeholder is available.
        if (!this._bottomPlaceholder) {
          console.error("The expected placeholder (Bottom) was not found.");
          return;
        }
    
        if (this.properties) {
          let bottomString: string = this.properties.Bottom;
          if (!bottomString) {
            bottomString = "(Bottom property was not defined.)";
          }
    
          if (this._bottomPlaceholder.domElement) {
            this._bottomPlaceholder.domElement.innerHTML = `
            <div class="${styles.app}">
              <div class="${styles.bottom}">
                <i class="ms-Icon ms-Icon--Info" aria-hidden="true"></i> ${escape(
                  bottomString
                )}
              </div>
            </div>`;
          }
        }
      }
    }
    

    Обратите внимание на следующие особенности этого кода:

    • Используйте метод this.context.placeholderProvider.tryCreateContent для доступа к заполнителю.
    • Код расширения не должен предполагать, что ожидаемый заполнитель доступен.
    • Код ожидает настраиваемые свойства Top и Bottom. Если свойства существуют, они отображаются в заполнителях.
    • Обратите внимание, что путь к коду верхнего и нижнего заполнителей почти идентичный. Он отличается только используемыми переменными и определениями стиля.
    • Имена классов, определенные в таблице стилей, можно использовать напрямую, но это не рекомендуется. Если в коде не будет найдена ссылка на таблицу стилей, определенная в переменной styles, таблица стилей не будет добавлена на страницу. Это связано с тем, что неиспользуемые ссылки удаляются в процессе сборки.
  10. Добавьте приведенный ниже метод после метода _renderPlaceHolders(). В этом случае вы просто выводите сообщение в консоли, когда расширение удаляется со страницы.

    private _onDispose(): void {
      console.log('[HelloWorldApplicationCustomizer._onDispose] Disposed custom top and bottom placeholders.');
    }
    

Теперь можно проверить код в SharePoint Online.

Проверка кода

  1. В файле ./config/serve.json обновите раздел свойств файла, чтобы в ней были сообщения Top и Bottom .

    {
      "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/spfx-serve.schema.json",
      "port": 4321,
      "https": true,
      "serveConfigurations": {
        "default": {
          "pageUrl": "https://sppnp.sharepoint.com/sites/mySite/SitePages/myPage.aspx",
          "customActions": {
            "54328ea6-0591-4fbd-aadb-5dc51fd53235": {
              "location": "ClientSideExtension.ApplicationCustomizer",
              "properties": {
                "Top": "Top area of the page",
                "Bottom": "Bottom area of the page"
              }
            }
          }
        },
        "helloWorld": {
          "pageUrl": "https://sppnp.sharepoint.com/sites/mySite/SitePages/myPage.aspx",
          "customActions": {
            "54328ea6-0591-4fbd-aadb-5dc51fd53235": {
              "location": "ClientSideExtension.ApplicationCustomizer",
              "properties": {
                "Top": "Top area of the page",
                "Bottom": "Bottom area of the page"
              }
            }
          }
        }
      }
    }
    

    Примечание.

    GUID в приведенном выше фрагменте JSON является уникаьным идентификатором компонента расширения SPFx. Это определено в манифесте компонента. GUID в вашем решении будет другим, так как каждый идентификатор компонента уникален.

  2. Переключитесь в окно консоли, в котором выполняется gulp serve , и проверьте наличие ошибок. Gulp сообщает о любых ошибках в консоли; Прежде чем продолжить, вам потребуется исправить их. Если решение уже запущено, перезапустите его, чтобы мы получили обновленные параметры, примененные из файла serve.json .

    gulp serve
    
  3. Выберите Загрузить скрипты отладки, чтобы продолжить загрузку скриптов с домена localhost.

    Запрос разрешения на отладку манифеста на странице

Теперь на странице должны отображаться пользовательские верхний и нижний колонтитулы.

Пользовательские элементы верхнего и нижнего колонтитулов на странице

Дальнейшие действия

Поздравляем, вы создали собственные верхний и нижний колонтитулы с помощью настройщика заполнителей!

Далее см. статью Развертывание расширения в SharePoint (Hello World, часть 3). Вы узнаете, как развернуть и просмотреть расширение Hello World в семействе веб-сайтов SharePoint без использования параметров запроса отладки.