首页 > 解决方案 > 使用 Webpack Encore 在 Angular 数据表中找不到数据表

问题描述

我一直在将 Symfony 应用程序从 升级3.44.2.2,一切都很好,但我无法通过 yarn install 和 webpack encore 使用angular-datatables让 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 一起添加到我的 Webpackapp.js中:

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

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

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;




可能的解决方案

我已经尝试了以下 hacky 修复,但这意味着我必须将我的 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)

标签: javascriptangularjswebpacksymfony4webpack-encore

解决方案


您的项目具有datatables.netanddatatables.net-dt作为依赖项,并且它们都有自己的依赖项(jQuery>1.7)。如果你没有为你的项目指定一个 jQuery 版本,你的依赖树最终会得到最新版本的 jQuery,你的依赖也使用它。

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

但是如果你指定一个旧版本的 jQuery,你的依赖树最终会为你的依赖获取最新版本的 jQuery(yarn 会,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 安装将得到处理。


推荐阅读