Поделиться через


Разработка надстроек Office с помощью Angular

В этой статье приведены рекомендации по использованию Angular 2 и более поздних версий для создания надстройки Office в виде одностраничного приложения.

Примечание.

Вы можете поделиться опытом по использованию Angular для создания надстроек Office? Вы можете внести свой вклад в эту статью в GitHub или отправить свой отзыв, отправив сообщение о проблеме в репозитории.

Пример надстройки Office, созданной на платформе Angular, приведен в статье Надстройка на основе Angular для проверки стиля в приложении Word.

Установка определений типов TypeScript

Откройте окно Node.js и введите в командной строке следующую команду.

npm install --save-dev @types/office-js

Начальная загрузка должна находиться внутри Office.initialize

На любой странице, которая вызывает API JavaScript для Office, код должен сначала назначить функцию Office.initialize. Office вызывает эту функцию сразу после инициализации библиотек Office JavaScript. Если у вас нет кода инициализации, текст функции может быть пустым символом ,{} но не следует оставлять функцию Office.initialize неопределенной. Дополнительные сведения см. в разделе Инициализация надстройки Office.

Код начальной загрузки Angular должен вызываться внутри функции, которая назначается Office.initialize. Это гарантирует, что библиотеки Office JavaScript инициализируются в первую очередь. Вот простой пример, в котором показано, как это сделать. Этот код должен находиться в main.ts файле проекта.

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

Office.initialize = function () {
  const platform = platformBrowserDynamic();
  platform.bootstrapModule(AppModule);
};

Использование API диалогового окна Office с Angular

API диалогового окна надстройки Office позволяет надстройке открывать страницу в немодальном диалоговом окне, которое обменивается информацией со страницей main, которая обычно находится в области задач.

Метод displayDialogAsync принимает параметр, указывающий URL-адрес страницы, которая должна открыться в диалоговом окне. Надстройка может иметь отдельную HTML-страницу (отличную от базовой) для передачи в этот параметр, или вы можете передать URL-адрес маршрута в приложении Angular.

Важно помнить, что при передаче маршрута диалоговое окно создает новое окно с собственным контекстом выполнения. Базовая страница со всем ее кодом инициализации и начальной загрузки запускается снова в этом новом контексте, а возможным переменным присваиваются первоначальные значения в диалоговом окне. Этот метод запускает второй экземпляр одностраничного приложения в диалоговом окне. Код, изменяющий переменные в диалоговом окне, не изменяет версию этих переменных области задач. Аналогичным образом диалоговое окно имеет собственное хранилище сеансов (свойство Window.sessionStorage ), которое недоступно из кода в области задач.

Запуск обновления пользовательского интерфейса

В приложении Angular пользовательский интерфейс иногда не обновляется. Это происходит потому, что эта часть кода выполняется вне зоны Angular. Чтобы решить эту проблему, поместите код в зону, как показано в приведенном ниже примере.

import { NgZone } from '@angular/core';

export class MyComponent {
  constructor(private zone: NgZone) { }

  myFunction() {
    this.zone.run(() => {
      // The codes that need update the UI.
    });
  }
}

Использование наблюдаемого

Angular использует RxJS (реактивные расширения для JavaScript), а RxJS представляет Observable объекты и Observer для реализации асинхронной обработки. В этом разделе приведены краткие сведения об использовании Observables. Дополнительные сведения см. в официальной документации по RxJS .

Объект Observable отчасти похож на объект Promise: он возвращается сразу же после асинхронного вызова, но для его разрешения может потребоваться некоторое время. Но если Promise— это единственное значение (которое может быть объектом массивов), то Observable— это массив объектов (возможно, только с одним элементом). Благодаря этому код может вызывать такие методы массива, как concat, map и filter, для объектов Observable.

Отправка вместо вытягивания

Ваш код извлекает объекты Promise, назначая их переменным, тогда как объекты Observable рассылают свои значения объектам, которые подписаны на Observable. Подписчики — объекты Observer. Преимущество подхода, предусматривающего подобную рассылку, состоит в том, что позже можно добавлять в массив Observable новые элементы. При добавлении нового элемента все объекты Observer, подписанные на Observable, получают уведомление.

Настраивается Observer для обработки каждого нового объекта (называемого "следующим" объектом) с помощью функции. (Он также настроен для реагирования на ошибку и уведомление о завершении. Пример см. в следующем разделе.) По этой причине Observable объекты могут использоваться в более широком диапазоне сценариев, чем Promise объекты. Например, в дополнение к возврату Observable из вызова AJAX, способ возврата Promise, Observable можно вернуть из обработчика событий, например обработчика событий "изменено" для текстового поля. Каждый раз, когда пользователь вводит текст в поле, все подписанные Observer объекты немедленно реагируют, используя последний текст или текущее состояние приложения в качестве входных данных.

Дождитесь завершения всех асинхронных вызовов.

Чтобы обратный вызов выполнялся только при условии разрешения каждого элемента из набора объектов Promise, используйте метод Promise.all().

myPromise.all([x, y, z]).then(
  // TODO: Callback logic goes here.
)

Чтобы сделать то же самое с объектом Observable, используйте метод Observable.forkJoin().

const source = Observable.forkJoin([x, y, z]);

const subscription = source.subscribe(
  x => {
    // TODO: Callback logic goes here.
  },
  err => console.log('Error: ' + err),
  () => console.log('Completed')
);

Компиляция приложения Angular с помощью компилятора Ahead-of-Time (AOT)

Производительность приложения — одна из наиболее важных составляющих взаимодействия с пользователем. Компилятор Ahead-of-Time (AOT) позволяет оптимизировать приложение Angular, чтобы компилировать приложение во время сборки. Он полностью преобразовывает исходный код (шаблоны HTML и TypeScript) в эффективный код JavaScript. Если приложение скомпилировано с помощью компилятора AOT, в среде выполнения не будет происходить дополнительная компиляция, что ускорит обработку и выполнение асинхронных запросов для шаблонов HTML. Кроме того, уменьшится общий размер приложения, так как компилятор Angular не придется включать в распространяемый файл приложения.

Чтобы использовать компилятор AOT, добавьте --aot к команде ng build или ng serve:

ng build --aot
ng serve --aot

Примечание.

Дополнительные сведения о компиляторе Ahead-of-Time (AOT) приложения Angular см. в официальном руководстве.

Поддержка элемента управления WebView Trident

Старые клиенты Office используют элемент управления Webview Trident, предоставляемый Интернетом Обозреватель 11, как описано в разделе Браузеры и элементы управления веб-представления, используемые надстройками Office. Существует несколько Angular, которые следует учитывать, если надстройка должна поддерживать эти версии Office.

Angular зависит от нескольких window.history Api. Эти API не работают в веб-представлении Trident. Если эти API-интерфейсы не работают, надстройка может работать неправильно, например загрузить пустую область задач. Чтобы устранить эту проблему, Office.js обнуляет эти API. Однако при динамической загрузке Office.js AngularJS может загрузиться до Office.js. В этом случае следует отключить window.history API, добавив следующий код на страницуindex.html надстройки.

<script type="text/javascript">window.history.replaceState=null;window.history.pushState=null;</script>

Если надстройка поддерживает элементы управления браузера на основе Trident, вам потребуется использовать стратегию расположения хэша вместо стратегии расположения пути по умолчанию. Стратегия расположения пути требует поддержки HTML5, которую не предоставляет Trident.