2016-07-22 108 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>

相關問題