Руководство по созданию настраиваемых типов полей схемы в Apostrophe 3.

Типы полей схемы апострофа охватывают множество ситуаций, но мы можем добавить новую.

Поле схемы состоит из двух частей: части на стороне сервера и части на стороне браузера. Часть на стороне сервера отвечает за очистку ввода, полученного от браузера, а часть на стороне браузера отвечает за предоставление пользовательского интерфейса администратора.

Реализация серверной части

Любой модуль может зарегистрировать тип поля схемы на стороне сервера, например этот, что позволяет редакторам устанавливать «звездный рейтинг» от 1 до 5 звезд, как это часто можно увидеть в обзорах фильмов и ресторанов.

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

module.exports = {
  init(self) {
    self.addStarRatingFieldType();
  },
  methods(self) {
    return {
      addStarRatingFieldType() {
        self.apos.schema.addFieldType({
          name: 'starRating',
          convert: self.convertInput,
          vueComponent: 'InputStarRating'
        });
      },
      async convertInput(req, field, data, object) {
        const input = data[field.name];
        if ((data[field.name] == null) || (data[field.name] === '')) {
          if (field.required) {
            throw self.apos.error('notfound');
          }
        }
        object[field.name] = self.apos.launder.integer(input, field.def, 1, 5);
      }
    }
  }
}

В init, который запускается при инициализации модуля, мы вызываем наш метод addStarRatingFieldType. init — это правильное место для вызова кода, который должен выполняться при запуске процесса Apostrophe.

В addStarRatingFieldType мы вызываем self.apos.schema.addFieldType, чтобы добавить наш настраиваемый тип поля на стороне сервера. Мы предоставляем:

  • name, который можно использовать как параметр type при добавлении поля в схему.
  • convert, функция, которая будет использоваться для очистки ввода и копирования его в место назначения. Для этого мы передаем наш метод convertInput. Методы нашего модуля доступны как свойства self.
  • component, имя компонента Vue.js, которое будет отображаться при редактировании поля.

В convertInput мы очищаем ввод и копируем его из data[field.name] в object[field.name]. Поскольку мы не должны доверять браузеру, мы позаботимся о его санации с помощью модуля launder, который всегда доступен как apos.launder. Но мы можем проверять входные данные любым способом, если мы никогда не доверяем им.

Реализация браузерной части

Со стороны браузера нам понадобится специальный компонент Vue.js. Apostrophe предоставляет миксин Vue.js, AposInputMixin, который делает большую часть работы за нас.

<template>
  <AposInputWrapper
    :modifiers="modifiers" :field="field"
    :error="effectiveError" :uid="uid"
    :display-options="displayOptions"
  >
    <template #body>
      <div class="apos-input-wrapper">
        <button v-for="index in 5" :key="index" @click="setValue(index)" class="rating">{{ isActive(index) ? '☆' : '★' }}</button>
        <button class="clear" @click="clear">Clear</button>
      </div>
    </template>
  </AposInputWrapper>
</template>
<script>
import AposInputMixin from 'Modules/@apostrophecms/schema/mixins/AposInputMixin';
export default {
  name: 'InputStarRating',
  mixins: [ AposInputMixin ],
  methods: {
    validate(value) {
      if (this.field.required) {
        if (!value) {
          return 'required';
        }
      }
      return false;
    },
    setValue(index) {
      this.next = index;
    },
    clear() {
      this.next = null;
    },
    isActive(index) {
      return index <= this.next;
    }
  }
};
</script>
<style lang="scss" scoped>
  .rating {
    border: none;
    background-color: inherit;
    color: inherit;
    font-size: inherit;
  }
</style>

В нашем элементе шаблона AposInputWrapper заботится о том, чтобы украсить наше поле меткой, сообщениями об ошибках и т. д. Все, что нам нужно сделать, это передать некоторые стандартные реквизиты, которые нам предоставлены. Кроме того, наша обязанность — отображать текущие value для пользователя. Мы также добавляем обработчики событий для обработки пользовательского ввода, как описано ниже.

В нашем элементе script у нас всего две задачи: присвоение нового значения this.next всякий раз, когда значение изменяется, и проверка ввода пользователя. Остальную работу за нас сделает AposInputMixin.

Чтобы обновить this.next, мы реализуем методы, которые реагируют на события щелчка, такие как методы setValue и clear в этом примере. Чтобы проверить ввод пользователя, мы реализуем метод validate, который принимает текущее значение и проверяет ограничения, такие как свойство required поля. Если есть проблема, мы возвращаем код ошибки, такой как required, min или max, в противном случае мы возвращаем false. Конфигурация поля доступна нам как this.field.

Элемент style отвечает за CSS для этого компонента. Обратите внимание, что доступен синтаксис SCSS. Во избежание конфликтов рекомендуется использовать атрибут scoped.

ПРЕДУПРЕЖДЕНИЕ

Если сначала это не работает, убедитесь, что вы запустили npm run dev с настройкой переменной среды APOS_DEV=1, как объяснялось ранее. Это гарантирует, что пользовательский интерфейс администратора Apostrophe перестраивается при каждом изменении кода. Вы можете прекратить его использование, когда закончите изменение кода пользовательского интерфейса администратора.

Запуск нового типа поля схемы

Теперь мы можем использовать новый тип поля схемы в любой части или виджете так же, как мы использовали бы поле integer:

fields: {
  add: {
    rating: {
      type: 'starRating',
      label: 'Star Rating',
      required: true
    }
  }
}

Полученное значение затем доступно как свойство stars элемента или виджета с целочисленным значением от 1 до 5.

Больше контента на plainenglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Получите эксклюзивный доступ к возможностям написания и советам в нашем сообществе Discord.