API-интерфейс DataTables не определен в Symfony Webpack Encore - PullRequest
5 голосов
/ 15 апреля 2019

Я использую Webpack Encore с Symfony 3.4 (часть перехода на Symfony 4) .

У меня есть Datatables (установленные через NPM для node_modules), работающие с jQuery, но функции api, такие как .columns, возвращают: .column is not a function at

Версии пакета :

  • JQuery 2.14.4
  • Datatables 1.10.19
  • Webpack Encore 0.27.0

Webpack app.js :

global.$ = global.jQuery = require('jquery');
require('bootstrap');
global.moment = require('moment');
require('datatables.net-dt');
$.fn.dataTable = $.fn.DataTable = global.DataTable = require('datatables.net');

webpack.config.js

var Encore = require('@symfony/webpack-encore');

Encore
// directory where compiled assets will be stored
    .setOutputPath('code/web/build/')
    // public path used by the web server to access the output path
    .setPublicPath('/build')
    // only needed for CDN's or sub-directory deploy
    //.setManifestKeyPrefix('build/')

    .addEntry('site', './assets/js/site/app.js')

    // will require an extra script tag for runtime.js
    // but, you probably want this, unless you're building a single-page app
    .enableSingleRuntimeChunk()

    .cleanupOutputBeforeBuild()
    .enableSourceMaps(!Encore.isProduction())
    // enables hashed filenames (e.g. app.abc123.css)
    .enableVersioning(Encore.isProduction())

// uncomment if you use TypeScript
//.enableTypeScriptLoader()

// uncomment if you use Sass/SCSS files
//.enableSassLoader()

// uncomment if you're having problems with a jQuery plugin
//.autoProvidejQuery()
;

module.exports = Encore.getWebpackConfig();

Пример Javascript в template.html.twig (расширяет базовый html-файл) :

{{ encore_entry_script_tags('site') }}

<script type="text/javascript">
$(document).ready(function() {
    var $dtable;

    $dtable = $('#simpleTable')
                        .DataTable({
                            data: data,
                            deferRender: true,
                            scrollX: false,
                            searching: true,
                            paging: true,
                            pageLength: 25});

    console.log($dtable);

    // Error occurs here
    var column = $dtable.column(index);
});
</script>

Журнал консоли $dtable сразу после создания экземпляра выводит следующее, что, кажется, подтверждает, что экземпляр Api не создан?

dtable instance

Возможно ли это связано с загрузчиком DataTable, который использует метод AMD из-за Webpack?

jquery.dataTables.js

(function( factory ) {
    "use strict";
    if ( typeof define === 'function' && define.amd ) {
        define( ['jquery'], function ( $ ) {
            return factory( $, window, document );
        } );
    }
    else if ( typeof exports === 'object' ) {
        module.exports = function (root, $) {
            if ( ! root ) {
                // CommonJS environments without a window global must pass a
                // root. This will give an error otherwise
                root = window;
            }
            if ( ! $ ) {
                $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
                    require('jquery') :
                    require('jquery')( root );
            }
            return factory( $, root, root.document );
        };
    }
    else {
        factory( jQuery, window, document );
    }
}

Ответы [ 4 ]

2 голосов
/ 18 апреля 2019

Здесь может быть проблема с загрузчиком AMD,

Можете ли вы попробовать отключить загрузчик AMD , чтобы увидеть, работает ли он:

var config = Encore.getWebpackConfig();

config.module.rules.unshift({
  parser: {
    amd: false,
  }
});

module.exports = config;

В противном случае вы можете попытаться заставить его работать с AMD Loader : сначала установить DataTables:

npm install datatables.net

Затем стиль DataTables (начальная загрузка):

npm install datatables.net-bs

Затем плагин import-loader

Измените свой webpack.config.js , чтобы сделать исключение для таблиц:

module: {
  loaders: [
      {
          test: /datatables\.net.*/,
          loader: 'imports?define=>false'
      }
  ]
}

Теперь вы сможетеиспользовать DataTables:

import 'datatables.net';
import dt from 'datatables.net-bs';
dt(window, $);


//And now use it
$('#exampleDatatable').DataTable();
0 голосов
/ 23 апреля 2019

Документация DataTables для использования с NPM показывает, что экспорт - это функция, возвращающая API DataTable.

var dt = require( 'datatables.net' )(); // N.b. the extra parenthesis.

Так что, вероятно, вам потребуется изменить глобальное назначение;что-то вроде этого может работать:

$.fn.dataTable = $.fn.DataTable = global.DataTable = require('datatables.net')(); // N.b. the extra parentheses.
0 голосов
/ 20 апреля 2019

Может быть, это глупая идея ... но каково значение data в вашем вызове, определенном по шаблону $('#simpleTable').DataTable({data:data, ...}) вызов?

В соответствии с документами (3-й абзац) установка параметра data (даже с пустым значением) приведет к переопределению данных из таблицы.Если ваше значение data не определено, это может превратить вашу таблицу с данными в овощ * в глазах DataTable.

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

Если, однако, они содержат полезные данные, не могли бы вы опубликовать какой-нибудь пример?; О)

0 голосов
/ 17 апреля 2019

Я вижу проблему со строкой:

$.fn.dataTable = $.fn.DataTable = global.DataTable = require('datatables.net');

dataTable() и DataTable() не эквивалентны .

Правильные функции будут добавлены в Jquery на заводе, их не нужно устанавливать.На самом деле, если я могу догадаться, приведенный выше код будет перезаписан DataTable() с dataTable().

Измените на:

require('datatables.net');

Это должно работать.

...