我正在使用ajax-datatables-rails。下面是我的数据表的JS。我想将javascript转换为等效的Opal.rb。

jQuery(document).ready(function() {
  var table = $('#organizations-datatable');
  var token = $('meta[name=csrf-token]').attr('content');
  table.DataTable({
    "processing": true,
    "serverSide": true,
    "ajax": {
      "url": "/organizations/datatable.json",
      "type": 'POST',
      "beforeSend": function (xhr) {
          xhr.setRequestHeader('X-CSRF-Token', token)
        }
    },
    "pagingType": "full_numbers",
    "destroy": true,
    "columns": [
      {"data": "name"},
      {"data": "desc"},
      {"data": "industry"},
      {"data": "tags"}
    ],
    "iDisplayLength": 25
  });
});

它包括将CSRF token 添加到对数据的ajax请求中。

我希望我们所有的JavaScript都被编写为蛋白石,以提高可读性,等等。请不要争论这种选择,我只想了解如何通过opal/rails-ujs/opal-jquery将其用作Opalrb

下面的蛋白石与上面的JS并没有达到相同的效果。谁能帮我理解原因?

Element.expose :DataTable

Document.ready? do
  token     = Element['meta[name=csrf-token]'].attr('content');
  settings  = {
      "processing": true,
      "serverSide": true,
      "ajax": {
        "url": "/organizations/datatable.json",
        "type": 'POST',
        "beforeSend": lambda do
          xhr = `new window.XMLHttpRequest()`
          xhr.setRequestHeader('X-CSRF-Token', token)
        end
      },
      "pagingType": "full_numbers",
      "destroy": true,
    "columns": [
      {"data": "name"},
      {"data": "desc"},
      {"data": "industry"},
      {"data": "tags"}
    ]
    }
  Element['#organizations-datatable'].DataTable(settings.to_n)

end

我在这里想念什么?为什么这个蛋白石不好呢?

编辑:这是我的工作方式,这可以确保POST适用于此:

Rails.application.routes.draw do
    concern :with_datatable do
        post 'datatable', on: :collection
    end
    resources :organizations,   concerns: [:with_datatable]
end

这是我使用gem的相关 Controller 和数据表代码:

class OrganizationsController < ApplicationController
    def index
        @title              = "Organizations"
        @page_description   = "Organization data warehouse"
        @page_icon          = "institution"
        @organization       = Organization.new
        @load               = {data_table: true}
        @menu               = Menu.new

      respond_to do |format|
        format.html
        format.json { render json: OrganizationDatatable.new(params) }
      end

    end

    def datatable
        logger.ap "datatable params: #{params}"
        respond_to do |format|
            format.json { render json: OrganizationDatatable.new(params) }
        end
    end

    def get_raw_records
        Organization.all
    end
    def create

    end
    def edit

    end
    def destroy

    end

    def show
    end

    def update
    end

    def new
    end
end

这是数据表

class OrganizationDatatable < AjaxDatatablesRails::ActiveRecord

  extend Forwardable
  include ActionView::Helpers::TextHelper

  def_delegator :@view, :link_to

  def view_columns
    # Declare strings in this format: ModelName.column_name
    # or in aliased_join_table.column_name format

    @view_columns ||= {
      # id:       { source: "Organization.id"           },
      name:     { source: "Organization.name",cond: :like, searchable: true, orderable: true          },
      desc:     { source: "Organization.description",cond: :like, searchable: true, orderable: true   },
      industry: { source: "Organization.industry",cond: :like, searchable: true, orderable: true      },
      tags:     { source: "Organization.tag_list", searchable: false, orderable: false      }
    }
  end

  def data
    records.map do |record|
      {
        id:       record.id,
        name:     record.name,
        desc:     truncate(record.description,length: 240, separator: ' '),
        industry: record.industry,
        tags:     record.decorate.buttonize_tags,
        DT_RowId: record.id
      }
    end
  end

  def get_raw_records
    Organization.all
  end

end

最佳答案

我将从指出您的代码中的几个错误开始,

  • beforeSend中的代码有问题,请引用supplying-an-xhr-method,将其更改为以下代码,
    "beforeSend": lambda do |xhr|`xhr.setRequestHeader('X-CSRF-Token', token)`

  • 像上面的语句一样,将xhr语句包含在(`)反引号中
  • 列应具有二维数组,而不是对象数组,
    "columns": [ ["data": "name"], ["data": "desc"], ["data": "industry"], ["data": "tags"]]

  • 其余代码看起来不错。

    下面是经过测试的代码,
    Element.expose :DataTable
    Document.ready? do
      token     = Element['meta[name=csrf-token]'].attr('content');
      settings  = {
          "ajax": {
            "url": "/data.json",
            "type": 'POST',
            "beforeSend": lambda do |xhr|
              `xhr.setRequestHeader('X-CSRF-Token', token)`
            end
          },
          "pagingType": "full_numbers",
          "destroy": true,
        "columns": [
          ["data": "Name"],
          ["data": "Position"],
          ["data": "Office"],
          ["data": "Extn."],
          ["data": "Start"],
          ["data": "Salary"]
        ]
        }
      Element['#organizations-datatable'].DataTable(settings.to_n)
    
    end
    

    确保Rails应用程序的公用文件夹中有data.json文件,其内容如下:
    {
        "data": [
          [
            "Tiger Nixon",
            "System Architect",
            "Edinburgh",
            "5421",
            "2011/04/25",
            "$320,800"
          ],
          [
            "Garrett Winters",
            "Accountant",
            "Tokyo",
            "8422",
            "2011/07/25",
            "$170,750"
          ],
          [
            "Ashton Cox",
            "Junior Technical Author",
            "San Francisco",
            "1562",
            "2009/01/12",
            "$86,000"
          ],
          [
            "Cedric Kelly",
            "Senior Javascript Developer",
            "Edinburgh",
            "6224",
            "2012/03/29",
            "$433,060"
          ],
          [
            "Airi Satou",
            "Accountant",
            "Tokyo",
            "5407",
            "2008/11/28",
            "$162,700"
          ],
          [
            "Brielle Williamson",
            "Integration Specialist",
            "New York",
            "4804",
            "2012/12/02",
            "$372,000"
          ],
          [
            "Herrod Chandler",
            "Sales Assistant",
            "San Francisco",
            "9608",
            "2012/08/06",
            "$137,500"
          ],
          [
            "Rhona Davidson",
            "Integration Specialist",
            "Tokyo",
            "6200",
            "2010/10/14",
            "$327,900"
          ],
          [
            "Colleen Hurst",
            "Javascript Developer",
            "San Francisco",
            "2360",
            "2009/09/15",
            "$205,500"
          ],
          [
            "Sonya Frost",
            "Software Engineer",
            "Edinburgh",
            "1667",
            "2008/12/13",
            "$103,600"
          ],
          [
            "Jena Gaines",
            "Office Manager",
            "London",
            "3814",
            "2008/12/19",
            "$90,560"
          ],
          [
            "Quinn Flynn",
            "Support Lead",
            "Edinburgh",
            "9497",
            "2013/03/03",
            "$342,000"
          ],
          [
            "Charde Marshall",
            "Regional Director",
            "San Francisco",
            "6741",
            "2008/10/16",
            "$470,600"
          ],
          [
            "Haley Kennedy",
            "Senior Marketing Designer",
            "London",
            "3597",
            "2012/12/18",
            "$313,500"
          ],
          [
            "Tatyana Fitzpatrick",
            "Regional Director",
            "London",
            "1965",
            "2010/03/17",
            "$385,750"
          ],
          [
            "Michael Silva",
            "Marketing Designer",
            "London",
            "1581",
            "2012/11/27",
            "$198,500"
          ],
          [
            "Paul Byrd",
            "Chief Financial Officer (CFO)",
            "New York",
            "3059",
            "2010/06/09",
            "$725,000"
          ],
          [
            "Gloria Little",
            "Systems Administrator",
            "New York",
            "1721",
            "2009/04/10",
            "$237,500"
          ],
          [
            "Bradley Greer",
            "Software Engineer",
            "London",
            "2558",
            "2012/10/13",
            "$132,000"
          ],
          [
            "Dai Rios",
            "Personnel Lead",
            "Edinburgh",
            "2290",
            "2012/09/26",
            "$217,500"
          ],
          [
            "Jenette Caldwell",
            "Development Lead",
            "New York",
            "1937",
            "2011/09/03",
            "$345,000"
          ],
          [
            "Yuri Berry",
            "Chief Marketing Officer (CMO)",
            "New York",
            "6154",
            "2009/06/25",
            "$675,000"
          ],
          [
            "Caesar Vance",
            "Pre-Sales Support",
            "New York",
            "8330",
            "2011/12/12",
            "$106,450"
          ],
          [
            "Doris Wilder",
            "Sales Assistant",
            "Sidney",
            "3023",
            "2010/09/20",
            "$85,600"
          ],
          [
            "Angelica Ramos",
            "Chief Executive Officer (CEO)",
            "London",
            "5797",
            "2009/10/09",
            "$1,200,000"
          ],
          [
            "Gavin Joyce",
            "Developer",
            "Edinburgh",
            "8822",
            "2010/12/22",
            "$92,575"
          ],
          [
            "Jennifer Chang",
            "Regional Director",
            "Singapore",
            "9239",
            "2010/11/14",
            "$357,650"
          ],
          [
            "Brenden Wagner",
            "Software Engineer",
            "San Francisco",
            "1314",
            "2011/06/07",
            "$206,850"
          ],
          [
            "Fiona Green",
            "Chief Operating Officer (COO)",
            "San Francisco",
            "2947",
            "2010/03/11",
            "$850,000"
          ],
          [
            "Shou Itou",
            "Regional Marketing",
            "Tokyo",
            "8899",
            "2011/08/14",
            "$163,000"
          ],
          [
            "Michelle House",
            "Integration Specialist",
            "Sidney",
            "2769",
            "2011/06/02",
            "$95,400"
          ],
          [
            "Suki Burks",
            "Developer",
            "London",
            "6832",
            "2009/10/22",
            "$114,500"
          ],
          [
            "Prescott Bartlett",
            "Technical Author",
            "London",
            "3606",
            "2011/05/07",
            "$145,000"
          ],
          [
            "Gavin Cortez",
            "Team Leader",
            "San Francisco",
            "2860",
            "2008/10/26",
            "$235,500"
          ],
          [
            "Martena Mccray",
            "Post-Sales support",
            "Edinburgh",
            "8240",
            "2011/03/09",
            "$324,050"
          ],
          [
            "Unity Butler",
            "Marketing Designer",
            "San Francisco",
            "5384",
            "2009/12/09",
            "$85,675"
          ],
          [
            "Howard Hatfield",
            "Office Manager",
            "San Francisco",
            "7031",
            "2008/12/16",
            "$164,500"
          ],
          [
            "Hope Fuentes",
            "Secretary",
            "San Francisco",
            "6318",
            "2010/02/12",
            "$109,850"
          ],
          [
            "Vivian Harrell",
            "Financial Controller",
            "San Francisco",
            "9422",
            "2009/02/14",
            "$452,500"
          ],
          [
            "Timothy Mooney",
            "Office Manager",
            "London",
            "7580",
            "2008/12/11",
            "$136,200"
          ],
          [
            "Jackson Bradshaw",
            "Director",
            "New York",
            "1042",
            "2008/09/26",
            "$645,750"
          ],
          [
            "Olivia Liang",
            "Support Engineer",
            "Singapore",
            "2120",
            "2011/02/03",
            "$234,500"
          ],
          [
            "Bruno Nash",
            "Software Engineer",
            "London",
            "6222",
            "2011/05/03",
            "$163,500"
          ],
          [
            "Sakura Yamamoto",
            "Support Engineer",
            "Tokyo",
            "9383",
            "2009/08/19",
            "$139,575"
          ],
          [
            "Thor Walton",
            "Developer",
            "New York",
            "8327",
            "2013/08/11",
            "$98,540"
          ],
          [
            "Finn Camacho",
            "Support Engineer",
            "San Francisco",
            "2927",
            "2009/07/07",
            "$87,500"
          ],
          [
            "Serge Baldwin",
            "Data Coordinator",
            "Singapore",
            "8352",
            "2012/04/09",
            "$138,575"
          ],
          [
            "Zenaida Frank",
            "Software Engineer",
            "New York",
            "7439",
            "2010/01/04",
            "$125,250"
          ],
          [
            "Zorita Serrano",
            "Software Engineer",
            "San Francisco",
            "4389",
            "2012/06/01",
            "$115,000"
          ],
          [
            "Jennifer Acosta",
            "Junior Javascript Developer",
            "Edinburgh",
            "3431",
            "2013/02/01",
            "$75,650"
          ],
          [
            "Cara Stevens",
            "Sales Assistant",
            "New York",
            "3990",
            "2011/12/06",
            "$145,600"
          ],
          [
            "Hermione Butler",
            "Regional Director",
            "London",
            "1016",
            "2011/03/21",
            "$356,250"
          ],
          [
            "Lael Greer",
            "Systems Administrator",
            "London",
            "6733",
            "2009/02/27",
            "$103,500"
          ],
          [
            "Jonas Alexander",
            "Developer",
            "San Francisco",
            "8196",
            "2010/07/14",
            "$86,500"
          ],
          [
            "Shad Decker",
            "Regional Director",
            "Edinburgh",
            "6373",
            "2008/11/13",
            "$183,000"
          ],
          [
            "Michael Bruce",
            "Javascript Developer",
            "Singapore",
            "5384",
            "2011/06/27",
            "$183,000"
          ],
          [
            "Donna Snider",
            "Customer Support",
            "New York",
            "4226",
            "2011/01/25",
            "$112,000"
          ]
        ]
      }
    

    opal添加到Gemfile
    gem 'opal-rails'
    
    gem 'opal-jquery'
    
    application.js.rb内容,
    require 'opal'
    require 'jquery'
    require 'opal-jquery'
    require 'datatables.min'
    require_tree '.'
    

    datatables.min.js文件添加到app/assets/javascripts文件夹

    html,
    <table id="organizations-datatable" class="display" style="width:100%">
        <thead>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Extn.</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Extn.</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </tfoot>
    </table>
    

    注意:-如果要使其与POST一起使用,则必须调整config/routes.rb

    在routes.rb中为您的json文件添加以下条目,

    对我来说,
    post '/data.json', :to => redirect('/data.json')
    

    对你来说,
    post '/organizations/datatable.json', :to => redirect('/organizations/datatable.json')
    

    完整代码在这里 https://gitlab.com/shoyebsheikh/opal-datatables

    Ajax数据表Rails gem解决方案:

    您可以将以下行添加到您的路由中,假设这就是数据源,
    post '/organizations/datatable.json', :to => redirect('/organizations/datatable.json')
    

    您的 Controller 应该像
    class OrganizationsController < ApplicationController
        def datatable
            params["columns"] ||= { "0" => {"data" => "" } }
            params["length"]  ||= -1
            respond_to do |format|
                format.html
                format.json { render json: OrganizationDatatable.new(params) }
            end
        end
    end
    

    和您的数据表如下,
    class OrganizationDatatable < AjaxDatatablesRails::ActiveRecord
    
      def view_columns
        # Declare strings in this format: ModelName.column_name
        # or in aliased_join_table.column_name format
    
        @view_columns ||= {
          # id:       { source: "Organization.id"           },
          name:     { source: "Organization.name",cond: :like, searchable: true, orderable: true          },
          desc:     { source: "Organization.description",cond: :like, searchable: true, orderable: true   },
          industry: { source: "Organization.industry",cond: :like, searchable: true, orderable: true      },
          tags:     { source: "Organization.tag_list", searchable: false, orderable: false      }
        }
      end
    
      def data
        records.map do |record|
          {
            # id:       record.id,
            name:     record.name,
            desc:     truncate(record.description,length: 240, separator: ' '),
            industry: record.industry,
            tags:     record.decorate.buttonize_tags,
            DT_RowId: record.id
          }
        end
      end
    
      def get_raw_records
        Organization.all
      end
    
    end
    

    在您的organizations.js.rb中输入了蛋白石代码,
    Document.ready? do
      token     = Element['meta[name=csrf-token]'].attr('content');
      settings  = {
          "ajax": {
            "url": Element['#organizations-datatable'].data('source'),
            "type": 'POST',
            "beforeSend": lambda do |xhr|
              `xhr.setRequestHeader('X-CSRF-Token', token)`
            end
          },
          "pagingType": "full_numbers",
          "destroy": true,
        "columns": [
          {"data": "name"},
          {"data": "desc"},
          {"data": "industry"},
          {"data": "tags"}
        ]
        }
      Element['#organizations-datatable'].dataTable(settings.to_n)
    
    end
    

    在html中
    <table id="organizations-datatable" data-source="<%= organizations_index_path(format: :json) %>">
      <thead>
        <tr>
          <th>Name</th>
          <th>Desc</th>
          <th>Industry</th>
          <th>tags</th>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>
    
    organizations_index_path可以是organizations_path,也可以是organization_index_pathorganization_path之类的单数,具体取决于您的 Controller 名称

    有关更多信息,请引用https://gitlab.com/shoyebsheikh/ajax-datatables-rails-with-opal

    注意:
  • 使用mysql2 gem。
  • 运行迁移并将条目从以下位置添加到表中
    rails CLI或手动在表中。
  • 如果在安装所有依赖项并运行迁移后运行项目,请访问http://localhost:3000/user/indexhttp://localhost:3000/hello_world/index
  • 09-11 14:52