【问题标题】:Populate Datatable from 2 different sources using jQuery使用 jQuery 从 2 个不同的来源填充数据表
【发布时间】:2021-06-04 18:59:20
【问题描述】:

我需要从 jQuery 的 2 个不同的 api 端点填充 https://datatables.net/

第一个端点(Owner Api)仅检索“驱动程序名称”, 第二个端点(VehicleDetail Api)检索“车辆名称和车牌”

服务器上的数据库如下,是一对多的关系(1个车主可能有多辆车)

1.表所有者:

  Fields
  -----------
  Id 
  Name

2。 TableVehicleDetail:

  Fields
  -----------
  Id
  Name
  NumberPlate
  OwnerId       (Foreign Key)
  

我的数据表有 3 列(司机姓名、车辆名称、车牌),我需要从两个 api 端点填充它。

Driver Name数据必须来自名为Owner的端点api,

VehicleName车牌号必须来自名为 VehicleDetail 的端点 api

我读到 Datatable 有一个名为 'ajax source' 的属性,我尝试过但无法实现。

关于 jQuery API,我使用 jquery Fetch API 从端点 api 检索数据。

以下是我使用的代码。对于两个端点(Owner 和 VehicleDetail api),我在同一页面上有两个类似的代码。

// ******** Owner Start

        getData();

        async function getData() {
            const response = await fetch('https://localhost:44389/api/owners');
            const settings = {
                method: 'get',
                headers: {
                    'Accept': 'application/json, text/plain, */*',
                    'Content-Type': 'application/json'
                }
            };
            const owner = await response.json();

            var arrayToString = JSON.stringify(Object.assign({}, owner));       // convert array to string
            var stringToJsonObject = JSON.parse(arrayToString);                 // convert string to json object

            return stringToJsonObject;
        }

        getData().then(owner => {
            owner;

            $.each(owner, function (index, value) {
                console.log(value.name);                // Here data can be displayed on console.log
            });

        });

// ******** Owner End

// ******** VehicleDetail Start

    getData();

    async function getData() {
        const response = await fetch('https://localhost:44389/api/vehicleDetail');
        const settings = {
            method: 'get',
            headers: {
                'Accept': 'application/json, text/plain, */*',
                'Content-Type': 'application/json'
            }
        };
        const vehicle = await response.json();

        var arrayToString = JSON.stringify(Object.assign({}, vehicle));       // convert array to string
        var stringToJsonObject = JSON.parse(arrayToString);                 // convert string to json object

        return stringToJsonObject;
    }

    getData().then(vehicle => {
        vehicle;

        $.each(vehicle, function (index, value) {
            console.log(value.name);                // Here data can be displayed on console.log
        });

    });

// ******** 车辆详情结束

【问题讨论】:

  • 您可能需要在将数据发送到 DataTables 之前合并数据。你试过吗?
  • 您没有详细说明您是如何使用车辆 API 的?
  • 和你看到的owner api一样。刚刚添加了代码。

标签: javascript jquery datatables


【解决方案1】:

假设来自两个不同数据源的 JSON 如下所示:

[
  {
    "id": "123",
    "driverName": "John"
  },
  {
    "id": "456",
    "driverName": "Mary"
  }
]

和:

[
  {
    "id": "1234",
    "vehicleName": "Ford",
    "ownerId": "123",
    "numberPlate": "ABC 555"
  },
  {
    "id": "2345",
    "vehicleName": "Citroen",
    "ownerId": "123",
    "numberPlate": "DEF 678"
  },
  {
    "id": "3456",
    "vehicleName": "Toyota",
    "ownerId": "456",
    "numberPlate": "GHK 987"
  }
]

然后您可以通过将车主姓名添加到每个车辆记录来合并它们 - 所以,像这样:

function fetchUrl(url) { 
  return $.ajax( {
    url: url,
    type: 'GET'
  } );
};

function merge(owners, vehicles) {
  // create a map, for owner ID to owner name lookups:
  let ownerMap = new Map();
  owners.forEach( (owner) => { 
    ownerMap.set(owner.id, owner.driverName);
  } )

  // add owner name to vehicle record:
  vehicles.forEach( (vehicle) => { 
    vehicle['driverName'] = ownerMap.get(vehicle['ownerId']);
  } )

  return vehicles;  
}

这是一种非常基本的方法,不会尝试考虑可能存在车主没有车、车没有车主、一车有多个车主等情况(因此,没有数据质量检查) .


查看端到端方法:

获取单独的数据集:

async function getTableData() {

  var ownersUrls = '[your URL here]';
  var vehiclesUrl = '[your URL here]';

  try {
    let owners = await fetchUrl(ownersUrls);
    let vehicles = await fetchUrl(vehiclesUrl);
    let dataSet = merge(owners, vehicles);
    initializeTable(dataSet);
  } catch(err) {
    console.log(err);
  }

}

function fetchUrl(url) { 
  return $.ajax( {
    url: url,
    type: 'GET'
  } );
};

要将数据传递给 DataTables,我会在脚本的开头添加:

getTableData();

最后是表格本身:

function initializeTable(dataSet) {
  $(document).ready(function() {
    $('#example').DataTable( {
      data: dataSet,
      columns: [
        { title: 'Driver Name', data: 'driverName' },
        { title: 'Vehicle Name',  data: 'vehicleName' },
        { title: 'Number Plate', data: 'numberPlate' }
      ]
    } );
  } );
}

更新

针对答案中的 cmets 进行调整,当我们将所有者合并到车辆记录中时,我们可以通过重命名所有者 name 字段来处理包含 name 字段的两个来源。

我更新的 JSON 结构,现在在两个数据集中都使用 name

[
  {
    "id": "123",
    "name": "John"
  },
  {
    "id": "456",
    "name": "Mary"
  }
]

和:

[
  {
    "id": "1234",
    "name": "Ford",
    "ownerId": "123",
    "numberPlate": "ABC 555"
  },
  {
    "id": "2345",
    "name": "Citroen",
    "ownerId": "123",
    "numberPlate": "DEF 678"
  },
  {
    "id": "3456",
    "name": "Toyota",
    "ownerId": "456",
    "numberPlate": "GHK 987"
  }
]

这里是完整的代码:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
  <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css">
  <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">

</head>

<body>

<div style="margin: 20px;">

    <table id="example" class="display dataTable cell-border" style="width:100%"></table>

</div>

<script type="text/javascript">

getTableData();

function initializeTable(dataSet) {
  $(document).ready(function() {
    $('#example').DataTable( {
      data: dataSet,
      columns: [
        { title: 'Driver Name', data: 'driverName' },
        { title: 'Vehicle Name',  data: 'name' },
        { title: 'Number Plate', data: 'numberPlate' }
      ]
    } );
  } );
}

async function getTableData() {

  var ownersUrls = 'your URL goes here';
  var vehiclesUrl = 'your URL goes here';

  try {
    let owners = await fetchUrl(ownersUrls);
    let vehicles = await fetchUrl(vehiclesUrl);
    let dataSet = merge(owners, vehicles);
    initializeTable(dataSet);
  } catch(err) {
    console.log(err);
  }

}

function fetchUrl(url) { 
  return $.ajax( {
    url: url,
    type: 'GET'
  } );
};

function merge(owners, vehicles) {

  // create a map for owner ID to owner name:
  let ownerMap = new Map();
  owners.forEach( (owner) => { 
    ownerMap.set(owner.id, owner.name);
  } )

  // add owner name to vehicle record:
  vehicles.forEach( (vehicle) => { 
    vehicle['driverName'] = ownerMap.get(vehicle['ownerId']);
  } )

  return vehicles;  
}

</script>

</body>
</html>

name 问题只需在此处创建一个名为 driverName 的字段即可处理:

vehicle['driverName'] = ...

并将所有者的姓名放入该字段。

DataTable 指的是我们创建的字段名:

{ title: 'Driver Name', data: 'driverName' }

【讨论】:

  • 感谢您帮助我。事实上,我收到错误消息说 javascript 参考错误:getTableData 中没有定义合并。我试图将let dataSet 声明为全局变量,但仍然出现相同的错误。我正在使用 jquery-3.5.1.js
  • 我更新到了最新的 jquery 3.6.0 code.jquery.com/jquery-3.6.0.js 但仍然遇到同样的错误。
  • 我尝试在没有数据的情况下使用合并,并且我还尝试使用这个小代码以 here 进行测试,但仍然遇到相同的错误。让 obj1 = { foo: 'bar', x: 42 }; let obj2 = { foo: 'baz', y: 13 }; let mergedObj1 = merge(obj1, obj2); console.log(mergedObj1);
  • 我使用了Object.assign,它成功了。但我还有一个小问题。真正的 api 端点/数据库表都有一个名为“name”的属性,因此 merge 函数不能将相同的属性名称合并到一个对象中。我更新了 OP。
  • 我在答案的末尾提供了一个 Update 部分 - 我展示了整个代码,因此您可以看到所有不同部分如何组合在一起。
猜你喜欢
  • 1970-01-01
  • 2011-09-20
  • 2017-08-01
  • 2021-08-29
  • 2020-10-28
  • 1970-01-01
  • 2022-10-06
  • 2021-02-18
  • 2020-10-14
相关资源
最近更新 更多