对于时间表应用程序,我有一个可观察的数组:
DayHrs
DayHrs包含5天或7天,具体取决于员工。 我有一个WeekHrs,这是一个计算字段。
当用户输入其中一个DayHrs的值时,我希望HKH的总字段立即更新。
所以在我的数据绑定中我想使用valueUpdate:' afterkeydown'。
但是我无法将其作为计算字段,因为可观察数组中的数组项本身不可观察。
根据Knockout文档:关键点:observableArray跟踪数组中的对象,而不是这些对象的状态。
那么我该如何解决这个问题呢?有没有办法迭代数组使每个项目都可观察(我还没有看到如何做到这一点)或者我应该指定一个更改事件?或其他什么?
答案 0 :(得分:2)
将“普通javascript对象”转换为具有可观察属性的视图模型有两种主要方式:
ko.mapping.fromJS
或如果您想使用选项2,我会给出答案。如果您想自动执行(1),最好查看文档和示例here。
在下面的代码中,我编写了一个将普通javascript对象和数组转换为ko.observable
和ko.observableArray
属性的示例。每个viewmodel都有一个构造函数或静态create
方法,它“知道”如何处理指定的数据格式。对于数据中的每个属性,您可以选择:
然后,您可以添加ko.computed
属性和方法,以使您的视图具有交互性。
var Day = function(initialHours) {
this.hours = ko.observable(initialHours || 0);
};
Day.create = function(data) {
return new Day(data.Hours);
}
var Week = function(initialDays) {
this.days = ko.observableArray(initialDays.map(Day.create));
this.totalHours = ko.pureComputed(function() {
return this.days().reduce(function(sum, day) {
return sum + parseInt(day.hours(), 10);
}, 0);
}, this);
};
Week.create = function(dayArray) {
return new Week(dayArray);
};
var Employee = function(employeeData) {
this.name = employeeData.Name;
this.workWeek = Week.create(employeeData.WorkWeek);
};
Employee.create = function(employeeData) {
return new Employee(employeeData);
};
var testData = [{
Name: "John Doe",
WorkWeek: [
{ Hours: 4 },
{ Hours: 8 },
{ Hours: 8 },
{ Hours: 8 },
{ Hours: 6 }
]
}];
var vm = {
employees: testData.map(Employee.create)
};
ko.applyBindings(vm);
input[type="number"] { width: 30px }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: employees">
<li>
<div data-bind="text: name"></div>
<div data-bind="with: workWeek">
<!-- ko foreach: days -->
<input data-bind="value: hours" type="number"/> -
<!-- /ko -->
<span data-bind="text: 'total: ' + totalHours()"></span>
</div>
</li>
</ul>