从 Coffeescript 到 ES6 使用 Rails webpacker,如何管理 类?

From Coffeescript to ES6 using Rails webpacker, how to manage classes?

我不是一个熟练的 javascript 专家。 我正在将一个非常旧的应用程序迁移到 webpacker。 我有很多这样的 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()

我已经在 webpacker 中为我的 Javascript 文件创建了一个结构。

我有一些特定于页面的脚本和一些全局脚本,我使用这样的 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 对象的方法。 上面的 coffeescript 很简单,但我也有一些复杂的对象,例如:

@封面={}

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 并在 webpacker 中添加 coffeescript 文件加载器,但我不明白如何在初始化文件中初始化我的咖啡定义对象(而不是像现在这样在咖啡文件中)

2) 从 coffee 转换成 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

举个例子:

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
}

而且在 esm 模块中您不再需要 iife