Добавление пользовательских параметров в виджет - PullRequest
3 голосов
/ 22 октября 2019

Допустим, мы создали простой виджет, который может иметь строку или поле richtext. Когда я вставляю виджет в HTML, я хотел бы указать, какое поле должно быть видимым / активным. Другими словами, я хотел бы добавить некоторые пользовательские параметры для виджета, который изменит его поведение. Виджет выглядит так:

{{
    apos.singleton(data.page, 'footerTitle', 'footerTitle', {
        controls: {
            movable: false,
            position: 'top-right'
        }
    })
}}

И я хотел бы сделать что-то вроде этого:

{{
    apos.singleton(data.page, 'footerTitle', 'footerTitle', {
        controls: {
            movable: false,
            position: 'top-right'
        },
        settings: {
            type: 'string',
            anotherParameter: 1,
            thirdParameter: false
        }
    })
}}

Позже (внутри index.js виджета) эти параметры будут обработаны соответственно:

...
beforeConstruct: function( self, options )
{
    if (type === 'string')
    {
        // Do some additional setup, magic, whatever...
    }
    switch (anotherParamter)
    {
        // Add some insane code here :)
    }
},
construct: function( self, options )
    {
        const superLoad = self.load;
        self.load = ( req, widgets, callback ) => superLoad( req, widgets, ( err ) =>
        {
            if( err )
            {
                return callback( err );
            }

            for( const widget of widgets )
            {
                // Some additional work here based on the initial settings.
            }

            return callback( null );
        } );
    }
...

Есть ли возможность добавить пользовательские параметры, опции в виджет (в версии 2.98.1 или новее в 3.0.0)?

1 Ответ

3 голосов
/ 29 октября 2019

Это невозможно, как показано здесь в Apostrophe 2.x, потому что параметры виджета передаются из шаблона, и шаблон может выполнять только синхронную работу. На этом этапе метод load модуля виджета уже запущен. Так что уже слишком поздно влиять на то, как все происходит.

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

В обоих случаях вы можете затем изменить поведение load в соответствии с ситуацией.

Для подхода с использованием подклассов одинВы можете написать второй модуль, который расширяет первый:

// in lib/modules/subclass-widgets
module.exports = {
  name: 'subclass',
  extend: 'original-widgets',
  construct: function(self, options) {
    var superLoad = self.load;
    self.load = function(req, widgets, callback) {
      // ... we can call superLoad if we want or completely replace it
    };
  }
}

В шаблоне вы можете указать вариант original, subclass или оба.

Для альтернативы select field,Вы можете использовать только один тип виджета:

// in lib/modules/cool-widgets/index.js
module.exports = {
  name: 'cool',
  addFields: [
    {
      name: 'subtype',
      label: 'Subtype',
      type: 'select',
      choices: [
        {
          label: 'One',
          value: 'one'
        },
        {
          label: 'Two',
          value: 'two'
        },
      ]
    }
  ]
  construct: function(self, options) {
    self.load = function(req, widgets, callback) {
      for (const widget of widgets) {
        if (widget.subtype === 'two') { ... }
      }
    };
  }

Лучший выбор зависит от того, собираетесь ли вы обычно предоставлять пользователю выбор каждый раз, а код не сильно расходится (используйте selectэлемент) или вы хотите ограничить то, что они могут делать в каждом шаблоне (вместо этого использовать подклассы и указывать только подкласс, который соответствует сценарию использования в каждом шаблоне).

Что касается версии 3.0, будут способыдостичь того, что вы изначально просили в 3.0. Во-первых, метод output - это метод async в 3.x. Это означает, что вы можете переопределить его и выполнить асинхронную работу с опциями. С другой стороны, 3.x поддерживает асинхронные компоненты в шаблонах:

https://github.com/apostrophecms/apostrophe/issues/1668

(закрыт, поскольку он реализован в ветке 3.0)

Однако выпуск 3.0еще немного свободного времени и еще не время начинать проекты на нем. Версия 2.x имеет поддержку предприятия до 2023 года, и, как сопровождающие, мы сегодня запускаем новые корпоративные проекты на 2.x, поэтому я бы не рекомендовал ждать.

3.0 разработка немного замедлилась этим летом, когда мы охватили ApostropheТехнологии превратились в его собственную компанию и взяли на себя дополнительную работу по поддержке предприятия на основе 2.x, но в долгосрочной перспективе это то, что позволяет нам гораздо более эффективно укомплектовать персонал и развивать 3.0 в ближайшие месяцы.

...