我刚刚开始使用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>
答案 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更新时更新,并且然后可以级联到计算的“金额”的更新。