2016-07-22 105 views
0

对于时间表应用程序我有可观察到的数组:可观察数组值更新

DayHrs

DayHrs包含任一5或7天,取决于该雇员。 我有一个总计WeekHrs这是一个计算字段。

当用户输入某个DayHrs的值时,我希望总的WeekHrs字段立即更新。

所以在我的数据绑定我想使用valueUpdate:'afterkeydown'。

但是,我不能让这是一个计算字段,因为可观察数组中的数组项目本身并不可观察。

根据Knockout文档:关键点:observableArray跟踪数组中的哪些对象,而不是这些对象的状态。

那么我该如何解决这个问题?有没有一种方法来遍历数组,使每个项目可观察(我还没有看到如何做到这一点),或者我应该指定一个更改事件?或者是其他东西?

回答

2

有转换的两种主要方式为 “普通javascript对象” 与可观察到的特性的ViewModels:

  1. 自动,通过ko.mapping.fromJS,或
  2. 手动。

如果您想要使用选项2,我会给出答案。如果您想自动执行(1),最好查看文档和示例here

在下面的代码中,我编写了一个示例,将纯javascript对象和数组转换为ko.observableko.observableArray属性。每个视图模型有一个构造函数或静态的“知道”如何处理指定的数据格式的方法create。对于数据的每个属性,你可以选择两种:

  1. 忽略它
  2. 使它成为一个普通的属性(它不会在您的视图模型时,它不是在一个视图中呈现服务于一个目的)(当它是在你看来)
  3. 让它观察到的(当需要在视图中进行更新的话)

然后静态渲染,您可以添加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>

相关问题