使用Webpack Encore在Angular数据表中找不到数据表

时间:2019-01-23 14:38:43

标签: javascript angularjs webpack symfony4 webpack-encore

我一直在将Symfony应用程序从3.4升级到4.2.2,一切都很好,但是我无法通过angular-datatables的yarn install和webpack encore使DataTables正常运行。

我如何设置

纱线安装

yarn add jquery@2.1.4
yarn add angular@1.4.8
yarn add datatables.net@1.10.19
yarn add datatables.net-dt@1.10.11
yarn add angular-datatables@0.6.2

将这些文件和jQuery一起添加到我的Webpack app.js中:

var $ = require('jquery');
require('datatables.net');
require('datatables.net-dt');
require('angular');
require('angular-datatables');

在我的Webpack配置文件中包含了app.js

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

Encore
    .setOutputPath('public/build/')
    .setPublicPath('/build')

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

    .enableSingleRuntimeChunk()
    .cleanupOutputBeforeBuild()
    .enableBuildNotifications()
    .enableSourceMaps(!Encore.isProduction())
    .enableVersioning(Encore.isProduction())
    .autoProvidejQuery()
;

module.exports = Encore.getWebpackConfig();

并通过以下方式将以上内容包含在我的前端模板中:

{{ encore_entry_script_tags('app') }}

错误

上面的结果导致以下Javascript错误,似乎表明无法访问DataTables API。

Uncaught TypeError: Cannot read property 'Api' of undefined
at initAngularDataTables (angular-datatables.js:478)
at Object.invoke (angular.js:4523)


/* @ngInject */
function initAngularDataTables() {
    if ($.fn.DataTable.Api) {
        /**
         * Register an API to destroy a DataTable without detaching the tbody so that we can add new data
         * when rendering with the "Angular way".
         */
        $.fn.DataTable.Api.register('ngDestroy()', function(remove) {
            remove = remove || false;




可能的解决方案

我已经尝试了以下黑客修复程序,但这意味着我必须将Angular代码存储在同一app.js文件中,否则它将无法正常工作。这也意味着某些功能仍然会失败...

global.$ = global.jQuery = require('jquery');

require('jquery-ui');
require('bootstrap');
require('admin-lte');
require('datatables.net-dt');
global.moment = require('moment');

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

错误

TypeError: _oTable.ngDestroy is not a function
    at _destroyAndCompile (angular-datatables.js:947)

1 个答案:

答案 0 :(得分:1)

您的项目具有datatables.netdatatables.net-dt作为依赖项,并且它们都有自己的依赖项(jQuery>1.7)。如果您没有为项目指定jQuery版本,则依赖项树将以jQuery的最新版本结尾,而该版本也由您的依赖项使用。

├─jquery@3.3.1
├─datatables.net@1.10.19
└─datatables.net-dt@1.10.11

但是,如果您指定了旧版本的jQuery,则依赖项树最终将为您的依赖项获取最新版本的jQuery(用纱做到了,npm却没有,我不知道为什么)。

├─jquery@2.1.4
├─datatables.net@1.10.19
│      └─jquery@3.3.1
└─datatables.net-dt@1.10.11
       └─jquery@3.3.1

结果,您的项目中有2个不同的jQuery。

const jQuery = require('jquery')
console.log(jQuery.fn.jquery) // logs 2.1.4
const DataTable = require('datatables.net')
console.log(DataTable.$.fn.jquery) // logs 3.3.1

由于DataTable将自身绑定到jQuery的封装实例,所以jQuery.fn.dataTable是 显然undefined。要解决此问题,只需在您的计算机中使用最新版本的jQuery 项目。或者,您也可以建议用yarn对所有依赖项使用固定版本的jQuery,向您的package.json文件中添加一个解析指令。

"dependencies": {
    "angular": "1.4.8",
    "angular-datatables": "0.6.2",
    "datatables.net": "1.10.19",
    "datatables.net-dt": "^1.10.19",
    "jquery": "2.1.4"
},
"resolutions": {
    "jquery": "2.1.4"
}

然后执行yarn install命令,您不需要的jQuery安装将得到处理。