首页 > 解决方案 > 淘汰赛JS自动保存速率限制

问题描述

这是一个小提琴https://jsfiddle.net/pqs142aw/

我想在用户停止更改时自动保存。我遇到的问题是对 ko.computedContext.isInitial() 的检查仅在初始页面加载期间发生,并且在对可观察对象进行更改后不会触发。

ko.computed(function () {
    var isInitial = ko.computedContext.isInitial();               
    if (isInitial) {
        console.log("init...");                         
    }
    else { 
       //doesn't get called
       console.log("saving...");            
       self.save(); 

    }}, self).extend({ rateLimit: { timeout: 1000, method: "notifyWhenChangesStop" } });

我怎样才能让它工作或有更好的方法?

标签: knockout.js

解决方案


我更改了一些内容来演示如何使这项工作:

  • 添加了一些输入,一个计算的和一个常数,以显示这将如何扩展。
  • 计算viewModel值更改为返回除此viewModel计算值之外的整个对象的 json 字符串。该例程ko.JS循环遍历所有可观察对象,因此从现在开始,当任何可观察对象发生变化时,都会触发计算。
  • 当触发计算时,将订阅添加到此计算以调用保存。

看看下面的例子:

var ViewModel = function() {
  var self = this;
  self.id = 1234;
  self.firstname = ko.observable();
  self.prefix = ko.observable();
  self.lastname = ko.observable();
  self.fullname = ko.computed(function() {
    return `${self.firstname() || ''} ${self.prefix() || ''} ${self.lastname() || ''}`
  });

  self.save = function(json) {
    console.log(`saved... ${json}`);
  };

  self.viewModel = ko.computed(function() {
    var vm = ko.toJS(self);
    delete vm.viewModel;
    return JSON.stringify(vm);
  }).extend({ rateLimit: { timeout: 1000, method: "notifyWhenChangesStop" } });

  self.viewModel.subscribe(function(json) {
    self.save(json);
  });
};

ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<p>Id: <span data-bind='text: id'></span></p>
<p>Firstname: <input data-bind='textInput: firstname' /></p>
<p>Firstname: <input data-bind='textInput: prefix' /></p>
<p>Lastname: <input data-bind='textInput: lastname' /></p>
<p>Fullname: <span data-bind='text: fullname'></span></p>


推荐阅读