【发布时间】:2016-10-05 20:55:06
【问题描述】:
这是我正在努力解决的问题。
1- 我正在使用映射插件来创建 Knockout ViewModel。从服务器端,我有一个复杂的对象,它有几个属性(与这个问题无关)。除了其他属性之外,我还有一个属性 TotalofExpenses 并且还有一个名为 Expenses 的列表(费用项目是一个具有金额和描述的对象)。映射插件将此列表转换为 ObservableArray 并将 TotalofExpenses 转换为 observalbe
2- 在 UI 我想实现以下
- 最初我想为费用项目提供一个输入。两个输入框(一个用于金额,一个用于描述)
- 一旦用户添加描述和费用金额(两者),我想显示另一个费用项目的输入框,并在某处显示当前费用总额(比如在表格底部)。随着用户不断添加更多费用,我不断呈现新的输入框并继续显示总费用
- 如果用户返回之前添加的费用项目并进行更改,请说更改金额,我想更新我的总金额。
以下是我试图实现上述功能的代码。它没有按预期工作。 注意:我试图只放置与此问题相关的代码
var data = @Html.Raw(Model.ToJson());
//Add total expenses TotalShiftExpenses
var mappingOptionsForTotalShiftExpenses = {
create: function(options) {
return new ComputeTotalShiftExpenses(options.data);
}
};
var Expense = function(data) {
var self = this;
self.ShiftId = ko.observable(@Model.Shift.Id),
self.Id = ko.observable(0),
self.Amount = ko.observable(0),
self.Description = ko.observable("");
}
function ComputeTotalShiftExpenses(data) {
var self = this;
var model = ko.mapping.fromJS(data, {}, self);
model.TotalShiftExpenses = ko.computed(function() {
var sum = 0;
for (var i = 0; i < model.Shift.ShiftExpenses().length; i++) {
// if ((parseFloat(model.Shift.ShiftExpenses()[i].Amount)) > 0) {
sum += parseFloat(model.Shift.ShiftExpenses()[i].Amount());
}
//Add empty Expense to Observable array
if (parseFloat(model.Shift.ShiftExpenses()[ (model.Shift.ShiftExpenses().length - 1)].Amount()) > 0) {
model.Shift.ShiftExpenses
.push( new Expense({ "ShiftId": 0, "Id": 0, "Amount": 0, "Description": "" }));
}
return sum.toFixed(2);
});
return model;
}
//Apply MappingOptions
var AppViewModel = ko.mapping.fromJS(data, mappingOptionsForTotalShiftExpenses);
$(document)
.ready(function() {
ko.applyBindings(AppViewModel);
});
通过上面的代码,我可以得到 - 第一个费用项目的第一个输入框 - 一旦我添加费用项目,它将显示为下一个项目设置的另一个输入框,并显示总计。 - 问题是当我尝试添加第二笔费用时,它不会触发任何事情(似乎第二组输入框是不可观察的)。但是,如果我在第一个费用项目中更改金额,它将触发可观察行为,并将正确地为这两个费用添加项目......并为第三个费用添加 UI 输入框。由于某种原因,最后一个输入框始终不会触发可观察的行为,但最后一个输入框之前的任何框都会触发。 注意:我发布的代码只是试图增加费用。
迫不及待地想听听一些淘汰赛专家的消息....提前非常感谢。
【问题讨论】:
标签: knockout.js