List knockout groups to smaller lists with objects

I have daily data for several employees and depending on the start and end times, which can mean a lot of data.

Thus, with the display plugin, I matched them into one large list, but I need them grouped by employees into smaller lists so that I can create tables for each employee (for example, models with a lower representation) that have filtering and sorting for this subsets of data.

Here is a basic example that I created with static data.

$(function () { var data = { Employees: [{ Id: 1, Name: "Employee1", Day: new Date(), Price: 12.54 }, { Id: 2, Name: "Employee2", Day: new Date(), Price: 112.54 }, { Id: 1, Name: "Employee1", Day: new Date(), Price: 12.54 }, { Id: 3, Name: "Employee3", Day: new Date(), Price: 12.54 }] }; // simulate the model to json conversion. from now on i work with the json var jsonModel = JSON.stringify(data); function employeeModel(data) { var employeeMapping = { 'copy': ["Id", "Name", "Day", "Price"] }; ko.mapping.fromJS(data, employeeMapping, this); } function employeeViewModel(data) { var self = this; var employeesMapping = { 'Employees': { create: function (options) { return new employeeModel(options.data); } } }; ko.mapping.fromJSON(data, employeesMapping, self); } var productsModel = new employeeViewModel(jsonModel); ko.applyBindings(productsModel); }); 
 table { border-collapse: collapse; } table, th, td { border: 1px solid black; } tr:nth-child(even) { background-color: white; } tr:nth-child(odd) { background-color: #C1C0C0; } 
 <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script> <table> <tbody data-bind="foreach: Employees"> <tr> <td><span data-bind="text:Id"></span> </td> <td><span data-bind="text:Name"></span> </td> <td><span data-bind="text:Day"></span> </td> <td><span data-bind="text:Price"></span> </td> </tr> </tbody> </table> 
+6
source share
1 answer

One possibility is to use the calculated value to group your data.

 self.EmployeeGroups = ko.pureComputed(function () { var employees = self.Employees(), index = {}, group = []; ko.utils.arrayForEach(employees, function(empl) { var id = ko.unwrap(empl.Id); if ( !index.hasOwnProperty(id) ) { index[id] = { grouping: { Id: empl.Id, Name: empl.Name }, items: [] }; group.push(index[id]); } index[id].items.push(empl); }); return group; }); 

will turn your data from a flat array into this:

  [{
     grouping: {
         Id: / * ... * /, 
         Name: / * ... * /
     }
     items: [/ * references to all employee objects in this group * /]
 }, {
     / * same * /
 }]

Expand the code snippet below to see it at work.

 $(function () { var data = { Employees: [{ Id: 1, Name: "Employee1", Day: new Date(), Price: 12.54 }, { Id: 2, Name: "Employee2", Day: new Date(), Price: 112.54 }, { Id: 1, Name: "Employee1", Day: new Date(), Price: 12.54 }, { Id: 3, Name: "Employee3", Day: new Date(), Price: 12.54 }] }; var jsonModel = JSON.stringify(data); function employeeModel(data) { var employeeMapping = { 'copy': ["Id", "Name", "Day", "Price"] }; ko.mapping.fromJS(data, employeeMapping, this); } function employeeViewModel(data) { var self = this; self.Employees = ko.observableArray(); self.EmployeeGroups = ko.pureComputed(function () { var employees = self.Employees(), index = {}, group = []; ko.utils.arrayForEach(employees, function(empl) { var id = ko.unwrap(empl.Id); if ( !index.hasOwnProperty(id) ) { index[id] = { grouping: { Id: empl.Id, Name: empl.Name }, items: [] }; group.push(index[id]); } index[id].items.push(empl); }); return group; }); // init var employeesMapping = { 'Employees': { create: function (options) { return new employeeModel(options.data); } } }; ko.mapping.fromJSON(data, employeesMapping, self); } var productsModel = new employeeViewModel(jsonModel); ko.applyBindings(productsModel); }); 
 table { border-collapse: collapse; } table, th, td { border: 1px solid black; } tr:nth-child(even) { background-color: #efefef; } tr:nth-child(odd) { background-color: #CCCCCC; } tr.subhead { background-color: #D6E3FF; font-weight: bold; } 
 <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script> <table> <!-- ko foreach: EmployeeGroups --> <tbody> <!-- ko with: grouping --> <tr class="subhead"> <td colspan="2"> <span data-bind="text: Id"></span> <span data-bind="text: Name"></span> </td> </tr> <!-- /ko --> <!-- ko foreach: items --> <tr> <td><span data-bind="text: Day"></span></td> <td><span data-bind="text: Price"></span></td> </tr> <!-- /ko --> </tbody> <!-- /ko --> </table> <pre data-bind="text: ko.toJSON($root, null, 2)" style="font-size: smallest;"></pre> 
+2
source

Source: https://habr.com/ru/post/982090/


All Articles