基于外部数组Knockout JS

时间:2017-01-10 20:30:13

标签: javascript html knockout.js

我刚刚开始使用Knockout并运行多个网站课程。 我有一个(可能是基本的)关于基于父数组的计算属性的问题:

鉴于以下代码,我如何使其工作,以便Amount中每个项目的my.vm.attendees属性始终为totalCost除以与会者人数。例如。每个收集金额中有4名与会者应为25人。 这应该在您添加和删除项目时自动更新。

<script type="text/javascript">
    $(function () {
        var total = 100;

        //Attendee construction
        my.Attendee = function () {
            this.Name = ko.observable();
            this.Amount = ko.computed(function () {
                return total / this.numberOfAttendees;
            }, my.vm);
        };

        my.vm = {
            //observable array of attendees
            attendees: ko.observableArray([new my.Attendee()]),
            addAttendee: function () {
                my.vm.attendees.push(new my.Attendee());
            },
            numberOfAttendees: function () {
                my.vm.attendees.lenght + 1; //zero based
            }
        }

        ko.applyBindings(my.vm);
    });
</script>

2 个答案:

答案 0 :(得分:1)

我可能会做这样的事情。

function attendee(name, amount) {
  var self = this;
  this.name = ko.observable(name);
  this.amount = ko.observable(amount);
}

function model() {
  var self = this;
  this.attendees = ko.observableArray();
  this.total = ko.computed(function() {
    var total = 0;
    ko.utils.arrayForEach(this.attendees(), function(item) {
      var value = parseFloat(item.amount());
      if (!isNaN(value)) {
        total += value;
      }
    });
    return total.toFixed(2);
  }, this);
  this.average = ko.pureComputed(function() {
    return self.total() / self.attendees().length;
  }, this);
  this.remove = function(row) {
    self.attendees.remove(row);
  }
  this.name = ko.observable('');
  this.amount = ko.observable('');
  this.add = function() {
    self.attendees.push(new attendee(self.name(), self.amount()));
    self.amount('');
    self.name('');
  }
}

var mymodel = new model();

$(document).ready(function() {
  ko.applyBindings(mymodel);
  mymodel.attendees.push(new attendee('Bob', 25));

});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-condensed">
  <thead>
    <tr>
      <th>Name</th>
      <th>Amount</th>
      <td>Delete</td>
    </tr>
  </thead>
  <tbody data-bind="foreach: attendees">
    <tr>
      <td data-bind="text:name"></td>
      <td data-bind="text:amount"></td>
      <td>
        <button class="btn btn-danger" data-bind="click: $parent.remove">
          X
        </button>
      </td>
    </tr>
  </tbody>
  <tfooter>
    <tr>
      <td colspan=2>Average:
        <span data-bind="text:average">
        </span>
      </td>
    </tr>
  </tfooter>
</table>

<form class="form form-inline">
  <label class="sr-only" for="inlineFormInput">Name</label>
  <input type="text" class="form-control" id="inlineFormInput" placeholder="enter name" data-bind="textInput: name">

  <label class="sr-only" for="inlineFormInputGroup">Amount</label>
  <div class="input-group ">
    <div class="input-group-addon">$</div>
    <input type="text" class="form-control" id="inlineFormInputGroup" placeholder="amount" data-bind="textInput: amount">
  </div>


  <button type="buttont" class="btn btn-primary" data-bind="click: add">add row </button>
</form>

答案 1 :(得分:0)

每当更新任何子观察值时,将重新计算计算的“金额”。因此,如果您希望触发更改,则需要使“total”成为可观察对象,并且您需要将“numberOfAttendees”设置为自身计算,以便在my.vm.attendees更新时更新,并且然后可以级联到计算的“金额”的更新。