От Coffeescript до ES6 с использованием Rails Webpacker, как управлять классами? - PullRequest
0 голосов
/ 20 апреля 2020

Я не очень опытный javascript эксперт. Я перенес очень старое приложение в веб-упаковщик. У меня есть много файлов coffeescript, таких как:

class @SectionTable
  constructor: ->
    @table  = $('#site_section')
    @_dnd()

  _dnd: ->
    @table.tableDnD onDrop: (table, row) ->
      data = $.tableDnD.serialize()
      $.ajax
        type: 'POST'
        url: '/admin/sections/reorder'
        data: data

$ -> new SectionTable()

Я уже создал структуру для своих Javascript файлов в веб-пакере.

У меня есть несколько страниц, специфицирующих c скрипты и некоторые глобальный сценарий, который я запускаю, используя файл init. js, подобный этому

import timePicker from './timePicker.js';
import Redactor from './redactor.js';

(function init() {
  const dtPicker = timePicker();
  const redactor = Redactor();
  document.addEventListener("turbolinks:load", () => {
    dtPicker.init();
    redactor.init();
  });
}());

И затем, внутри timePicker. js, я запускаю отдельные компоненты

import 'bootstrap-datetime-picker/js/bootstrap-datetimepicker.js';
import 'bootstrap-datetime-picker/js/locales/bootstrap-datetimepicker.it.js';

const timePicker = () => {
    const initDateTimePicker = () => {
      const dateTime = $('.datetime');
      if (dateTime.length > 0) {
        $('.datetime').datetimepicker({
           todayHighlight: true,
           autoclose: true,
           pickerPosition: 'bottom-left',
           todayBtn: true,
           format: 'hh:ii dd/mm/yyyy'
         });
      }
    };
    const init = () => {
      initDateTimePicker();
   };
   return {
     init,
   };
};

export default timePicker;

Я не могу найти способ настроить мои объекты coffeescript внутри новой логики c. Приведенный выше кофейный текст очень прост, но у меня также есть несколько сложных объектов, подобных этому:

@ Cover = {}

class Cover.Preview
  constructor: ->
    @elements    = {} # preview elements, for each tab/preview box
    @element     = $('#cover_format')
    @container   = $('#cover_preview')
    @button      = $('#change_format')
    @url         = @element.data('url')
    @setFormat()
    @bindChange()

  addElement: (element, position) ->
    position = element.position
    @elements[position] = element

  bindChange: ->
    @button.click (event) =>
      event.preventDefault()
      @setFormat()
      $.ajax
        url:      "#{@url}?format=#{@format}"
        dataType: 'html'
        success: (html) =>
          @container.html html
          @rebindDrag()
          @repopulate()

  setFormat: -> @format = @element.val()

  rebindDrag: ->
    Cover.FormElement.init()
    Cover.Preview.Tile.init()

  repopulate: ->
    for position, tile of Cover.Preview.Tile.all
      tile.redraw Cover.preview.elements[position]



$ ->
  Cover.preview = new Cover.Preview()

Я понимаю, что у меня есть несколько способов сделать это:

1) сохранить coffeescript и добавить загрузчик coffeescript-файлов в webpacker, но я не могу понять, как инициализировать объекты, определенные в кофе, внутри файла инициализации (а не в файле кофе, как сейчас)

2 ) конвертировать из кофе в ES6, я пытаюсь с онлайн-инструментом, и у меня есть этот результат

this.SectionTable = class SectionTable {
  constructor() {
    this.table  = $('#dday_section');
    this._dnd();
  }

  _dnd() {
    return this.table.tableDnD({onDrop(table, row) {
      const data = $.tableDnD.serialize();
      return $.ajax({
        type: 'POST',
        url: '/admin/sections/reorder',
        data
      });
    }
    });
  }
};

$(() => new SectionTable());

Как я могу добавить модульный подход? Поэтому я хочу создать новый SectionTable в моем файле инициализации.

1 Ответ

0 голосов
/ 21 апреля 2020

Просто пример:

import $ from 'jquery';

export class SectionTable {
  constructor() {
   this.table = $('#site_section');
   this._dnd();
}
  _dnd() {
   this.table.tableDnD.onDrop((table, row) => {
      const data = $.tableDnD.serialize();
      $.ajax({
        type: 'POST',
        url: '/admin/sections/reorder',
        data: data
      });
   });
  }
}
// if you need a single instance like seems to from your code
export default new SectionTable();
// otherfile.js
// this is just to show you how you can import only some classes from a file when
// export is used
import SectionTableSingleTon, { SectionTable } from './somewhere/SectionTable';

const sectionTable = new SectionTable();

просто будьте осторожны с 'this' с объектными методами. Если вам нужно передать его, привязайте его в конструкторе.

constructor() {
   this.someMethod = this.someMethod.bind(this);

}
attachListener(){
   $('button').click(this.someMethod);
}
somemethod(){
// correct this
}

И вам больше не нужен iife внутри модуля esm

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