knockoutjs,observables互相更新

时间:2013-03-17 10:53:45

标签: javascript knockout.js

我有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总是抛出太多的递归异常。

2 个答案:

答案 0 :(得分:3)

据我所知,你基本上需要两件事。

  1. 您想要在有人选择时计算“天数”字段 “endDate”[假设他们选择了“startDate”ofcourse]
  2. 您想要在有人更改时重新计算“endDate”字段 “天”字段
  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