Knockout可写计算的observable,创建一个计时器

时间:2015-09-15 02:01:47

标签: knockout.js

我正在尝试在knockoutjs中创建一个可写的可计算observable,我几乎已经完成但是它无法读取计算值。难道我做错了什么?

this.time_remaining = ko.computed({
    read: function() {
        return this.time_remaining; <!-- Does this need setInterval? -->
    },
    write: function() {
        window.setInterval(function() {
            this.time_remaining = moment('2015-09-14').countdown().toString();
            console.log(this.time_remaining) 
           <!-- The console shows a timer, that is exciting! -->
        }, 1000)

    },
    owner: this
});

但是,它仍然无法读取数据绑定中的值,并且无法正常工作。也许我完全错了。

<h4 data-bind="text: time_remaining" class="timer"></h4>

2 个答案:

答案 0 :(得分:0)

您的计算需要一个支持变量。

this.time;
this.time_remaining = ko.computed({
    read: function() {
         return this.time;
   } 
});

答案 1 :(得分:0)

您不需要为计时器计算可写。您可以在间隔中更改常规可观察量:

var ViewModel = function(countDownTo) { 
  var self = this;
  
  self.time_remaining = ko.observable();
  
  var updateCountdown = function() {
    var diff = moment.duration(countDownTo - moment());
    var textDiff = diff.hours() +":"+ diff.minutes() +":"+ diff.seconds();
    self.time_remaining(textDiff);
  };
  
  window.setInterval(updateCountdown, 1000);
  updateCountdown();
};

var then = moment().add(10, 'h'); // Fake it!

ko.applyBindings(new ViewModel(then));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<h4 data-bind="text: time_remaining" class="timer"></h4>

其他一些兴趣点:

  • 使用var self = this;惯用法使this可以在回调中清晰地访问,例如updateCountdown或可写计算;
  • 单独定义setInterval的回调(a),这样你可以在暴露它时对其进行单元测试;(b)这样你也可以第一次调用它而不是等待1000毫秒才能启动它;

如果你想禁止对observable进行偷偷摸摸的更新,我可以查看只读计算的值:

var ViewModel = function(countDownTo) { 
  var self = this;
  var my_time_remaining = ko.observable();

  var updateCountdown = function() {
    var diff = moment.duration(countDownTo - moment());
    var textDiff = diff.hours() +":"+ diff.minutes() +":"+ diff.seconds();
    my_time_remaining(textDiff);
  };

  self.time_remaining = ko.computed(function() { return my_time_remaining(); });

  window.setInterval(updateCountdown, 1000);
  updateCountdown();
};

或等效:

  self.time_remaining = ko.computed(my_time_remaining);

如果你真的想要或需要一个可写的计算机,请记住,this is the format

self.myComputed = ko.computed({
  read: function() {
    // Parameterless function, returning the value of an internal 
    // variable, perhaps dependent on another observable to trigger
    // automatic UI updates
  },
  write: function(newValue) {
    // Note the `newValue` parameter that's being passed from a
    // caller (the UI, a interval callback, etc).
  }
});