【问题标题】:Knockout writable computed observables, creating a timer淘汰可写计算的可观察对象,创建一个计时器
【发布时间】:2015-09-15 02:01:47
【问题描述】:

我正在尝试在 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>

【问题讨论】:

  • 您需要另一个属性作为支持变量。现在看起来您将计算值作为值返回,并且写入覆盖了计算值。

标签: knockout.js


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    你不需要一个可写的定时器计算。您可以在间隔上更改常规可观察对象:

    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; 习惯用法使thisupdateCountdown 或可写计算等回调中清晰可访问;
    • 单独定义 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).
      }
    });
    

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 2013-08-26
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 2014-04-24
      • 2017-09-02
      相关资源
      最近更新 更多