简体   繁体   中英

Calculate the sum of some inputs in knockout

Part of my HTML code:

<!-- ko foreach: teamMembers -->
    <tr>
      <!-- ko foreach: days -->
      <td>
       <!-- ko foreach: $data -->
          <input  type="text" data-bind="value: number1">
          <input  type="text" data-bind="value: number2">
        <!-- /ko -->   
      </td>
      <!-- /ko -->
      <td>Total sum</td>
      <td>
        <button class="btn" data-bind='click: $root.addShift'>
          Add shift
        </button>
      </td>
    </tr>
    <!-- /ko -->

The viewmodel code:

function TimeCardViewModel() {
    var self = this; 
    self.teamMembers=ko.observableArray();
    self.addShift = ko.pureComputed(function() { });               
}
$.ajax({
      type:"POST"  
      url: "/...json"
    }).then(function(data){   
      for (var i=0; i<data.length; i++)  {
        timeCardViewModel.teamMembers.push({days:data[i]});   
      }   
    },
      function(){
        console.log('failure');
      }
   )

days is an array of arrays ; each of the latter ones include one or more objects.Therefore, in the template, $data represents an array of objects which lie inside the days array! Each object has a number1 property and a number2 property.

I want to calculate the sum of the values of these two numbers for all the objects inside days which is an array of arrays and there are lots of them inside teamMembers which also is an array of arrays. So, I want this to be done for every element-array of teamMembers . How may I achieve that? I want addShift function to do that and get the sum inside <td>Total sum</td> which exists for every element of teamMembers .Sorry if not describing well the whole issue...

If you're working with these kinds of nested data, you might want to create viewmodels for each of your elements.

If I get your structure correctly there's:

  1. A time card, which contains
  2. Teammembers, which contain
  3. Days, which contain
  4. Shifts, which contain
  5. Two numbers

If you define specific objects for each of these elements you get a good overview of the logic behind your computed values.

For example:

  • the totalHours of a shift, is number1 + number2
  • the totalHours of a day, is the totalHours of each shift summed
  • etc.

Two things you'll benefit from using:

I'd suggest taking a look at the example below to get a feel for how you could structure the elements that make up your TimeCard . You might not need this many class levels, but it makes it easier to follow.

Note that I didn't put in any code to convert your JSON data to new viewmodel instances. If you need help with that, let me know in the comments.

 function Shift(hoursA, hoursB) { var self = this; this.hoursA = ko.observable(hoursA); this.hoursB = ko.observable(hoursB); // Computed 1: Adds `number1` to `number2` when one of them // changes this.totalHours = ko.pureComputed(function() { return self.hoursA() + self.hoursB(); }); }; function Day(initialShifts) { var self = this; this.shifts = ko.observableArray(initialShifts); // Computed 2: Adds the `totalHours` for each shift this.totalHours = ko.pureComputed(function() { return self.shifts().reduce(function(result, shift) { return result + shift.totalHours(); }, 0); }); }; function TeamMemberViewModel(initialDays) { var self = this; this.days = ko.observableArray(initialDays); // Computed 3: Adds the `totalHours` for each day this.totalHours = ko.pureComputed(function() { return self.days().reduce(function(result, day) { return result + day.totalHours(); }, 0); }); }; function TimeCardViewModel() { var self = this; this.teamMembers = ko.observableArray(); // Computed 4: Adds the `totalHours` for each member this.totalHours = ko.pureComputed(function() { return self.teamMembers().reduce(function(result, member) { return result + member.totalHours(); }, 0); }); }; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM