Как вызвать CreateMenu () из библиотеки скриптов приложений? - PullRequest
1 голос
/ 18 июня 2020

Я создаю библиотеку в Apps Script и хотел бы сделать ее достаточно самодостаточной. По сути, если кто-то хочет использовать эту библиотеку в своем листе Google, ему нужно просто вставить следующий код в свой скрипт листов

function onOpen(){
  myLib.initialize();
}

И это настроит лист по мере необходимости. Одна из вещей, которые я здесь делаю, - это добавление пункта меню в сам лист. Поэтому в моем коде библиотеки у меня будет что-то вроде:

function initialize(){
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Custom Menu')
      .addItem('First item', 'someCallback')
      .addToUi();
}

Проблема с этим подходом заключается в том, что при нажатии на пункт меню функция « someCallback » не может быть нашел. Это имеет смысл, поскольку он находится в отдельной библиотеке. Его следует вызывать с использованием точечной нотации, например: myLib.someCallback

Есть ли способ получить идентификатор библиотеки во время выполнения, чтобы я мог создать строку, необходимую для создания меню?

Я могу делать несколько вещей, которые не были моим первым выбором, например:

  • передавать строку « myLib » в функцию инициализации
  • введите « myLib » в функцию addItem() напрямую, но я думаю, что это не очень хорошая практика, что, если конечный пользователь изменит идентификатор с myLib к чему-то другому.

Может быть, есть какой-нибудь способ во время выполнения, которым я могу получить идентификатор библиотеки?

1 Ответ

1 голос
/ 19 июня 2020

Ответ:

К сожалению, на данный момент это невозможно.

Дополнительная информация:

Я проверил несколько вещей с использованием как ключевого слова this, так и функции eval() для динамического получения переопределенного идентификатора myLib или вызова someCallback непосредственно в функции initialize, но даже встраивания функции обратного вызова внутри initialize:

funciton initialize() {
  var cb = function someCallback() {
    // do stuff
  };

  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Custom Menu')
      .addItem('First item', 'cb')
      .addToUi();

или:

function initialize() {
  function someCallback() {
    //do stuff
  }
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Custom Menu')
      .addItem('First item', 'someCallback')
      .addToUi();
}

выдает ту же ошибку, если cb или someCallback не определены.

Проблемы с this:

Чтобы ответить на ваш прямой вопрос:

Может быть, есть какой-то способ во время выполнения, которым я могу получить идентификатор библиотеки?

Ответ - да. Тип.

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

function onOpen(){
  myLib.initialize(this);
}

И в myLib.initialize():

function initialize(name) {
  console.log(Object.keys(name));
}

Консоль показывает: ['myLib', 'onOpen']

Эта проблема заключается в том, что, хотя имена импортированных библиотек идут перед списком функции, определенные в сценарии пользователя, если было импортировано более одной библиотеки, вы не можете указать , какие ключей относятся к вашей библиотеке, а какие - к другим. В результате простой вызов name[0] не поможет.

Копание:

Я обратился к системе отслеживания проблем Google и обнаружил, что есть некоторые запросы функций, которые варианты использования очень схожи с вашим:

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

Существует также этот запрос связанной функции, который просит реализовать метод универсального стиля, который запускает метод, если метод библиотеки, который не выполняет Не существует называется:

Что делать:

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

Что касается обходных путей; Лучшее, что вы можете сделать тем временем, - это задокументировать, что функции initialize() необходимо передать идентифицирующее имя библиотеки. Это не изящное решение по любым стандартам, но, учитывая сложность this и запросы функций, которые еще предстоит реализовать, это может быть самый простой вариант.

Это могло бы быть возможным для l oop через массив Object.keys(this), но я чувствую, что это очень хитрый обходной путь, который может вызвать больше проблем, чем необходимо (особенно если, например, , у другого создателя библиотеки также есть функция под названием someCallback ...)

Я знаю, что в целом это плохие новости, но я надеюсь, что это будет полезно для вас!

Ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...