首页 > 解决方案 > 使用 jQuery 从 2 个不同的来源填充数据表

问题描述

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

第一个端点(Owner Api)仅检索“Driver name”,第二个端点(VehicleDetail Api)检索“Vehicle Name and Number Plate”

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

1. 桌主:

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

2. TableVehicleDetail :

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

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

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

VehicleName , Number Plate必须来自名为 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
        });

    });

// ******** VehicleDetail End

标签: javascriptjquerydatatables

解决方案


假设来自两个不同数据源的 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' }
      ]
    } );
  } );
}

更新

调整答案中的评论,当我们将所有者合并到车辆记录中时,我们可以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' }

推荐阅读