我有3个字段的视图模型
dateStart = ko.observable();
dateEnd = ko.observable();
days = ko.observable();
假设选择了startDate,每当选择endDate时,需要更新天数字段(days = endDate - startDate)。
当更新天字段时,我需要计算endDate(endDate = startDate + days)。
如何用knockoutjs完成这项工作?
谢谢!
我试过了 http://jsfiddle.net/NfG4C/6/,但我的js总是抛出太多的递归异常。
答案 0 :(得分:3)
据我所知,你基本上需要两件事。
解决此问题的一种方法是使用“可写”计算的Observable [http://knockoutjs.com/documentation/computedObservables.html]。请仔细阅读链接,但总的来说,“可写的计算可观察量”是基于某些“其他”可观察值而“计算”的值,反之亦然。
我冒昧地修改你的小提琴并将“天”改为计算可观察者。请看一下:http://jsfiddle.net/dJQnu/5/
this.days = ko.computed({
read: function () {
//debugger;
// here we simply need to calculate the days as => (days = endDate - startDate)
if (that.dateStart() && that.dateEnd()) {
var vacDayCounter = 0;
for (var curDate = new Date(that.dateStart()); curDate <= that.dateEnd(); curDate = curDate.addDays(1)) {
if (isDateCountsAsVacation(curDate)) {
vacDayCounter++;
}
}
//that.days(vacDayCounter);
return vacDayCounter;
}
},
write: function (newDays) {
if (newDays && !isNaN(newDays) && that.dateStart()) {
var tmpEndDate = new Date(that.dateStart())
appliedDays = 0;
while (appliedDays < newDays) {
if (isDateCountsAsVacation(tmpEndDate)) {
appliedDays++;
}
tmpEndDate = tmpEndDate.addDays(1);
}
if (tmpEndDate) {
that.dateEnd(tmpEndDate);
}
}
}
});
如果您注意到,我只是将您的代码(逻辑)重用于读写部分。在读取期间,我们“计算”observable本身的值,在这种情况下是“days”和写入期间(在用户更改实际“days”输入值的任何时候触发)我们重新计算“dateEnd”字段。
如果您有任何其他问题,请与我们联系。
希望这有帮助。
感谢。
答案 1 :(得分:1)
您会遇到一个回避问题,因为从订阅更新observable时也会触发observables subscribe方法。
您需要添加第四个成员updatedFromSubscriber
从tbe开始将其设置为false,在每个订阅方法中添加
if(this.updatedFromSubscriber)
return;
并在更新observable之前执行
this.updatedFromSubscriber = true
在更新observable
后将其设置为false