当使用ko.mapping更改任何属性时,knockout js更新脏标志

时间:2017-03-15 21:28:34

标签: knockout.js

我正在尝试向我的knockout js模型添加一个脏标志(我希望它是一个简单的任务),当任何属性被更改时,标志将更新。

我在发布之前完成了一些研究,发现大多数答案指向this blog post还有一个与帖子相关的小提琴,我试图遵循,但没有成功。

我还尝试使用jquery并在输入或选择元素发生更改时进行侦听,但是在填充输入时触发了onpage加载,因此该标志将始终设置为脏。

我的模型和示例之间的区别是我使用自动映射器

在示例中,它显示id有一个Realm标记。使用自动映射器时如何进行复制? (我添加了我的json模型,以防它提供“最佳”解决方案)

示例中的JS

add(_:update:)

我的json对象

Item

1 个答案:

答案 0 :(得分:1)

在最基本的实现中,全局脏标志所需要的只有三件事

  • 保持脏状态的状态变量(布尔标志)
  • 在根对象上使用ko.toJS或ko.toJSON的计算属性
  • 订阅函数,用于在计算属性更改时更新状态变量

如果你的viewmodel是用ko.mapping构建的,它可能看起来像这样:

var viewModel = function(jsonData){
  var self = this;

  ko.mapping.fromJS(jsonData, {}, this);

  self.isDirty = ko.observable(false);
  self.toJS = ko.computed(function(){
    return ko.toJS(self);
  });
  self.toJS.subscribe(function(value){
    self.isDirty(true);
  });
}

jsFiddle

之后,您可以添加额外的复杂性来存储初始的toJS()结果,并将其与新值进行比较,以查看数据是否确实已更改,或者是否只是将其设置回相同的数据。

正如博客接着说的那样,这不是最佳方式。任何更改都会导致计算器通过遍历视图模型中的整个可观察树来重新计算,这可能会花费很多。

这是我暂时使用的另一个版本,它仅在第一次进行更改时进行评估,然后只返回dirty = true。我很确定我从Ryan Niemeyer那里得到了这个,但我不记得在哪里。我在你引用的博客上没有看到一个非常喜欢它。

var viewModel = function(jsonData){
  var self = this;

  ko.mapping.fromJS(jsonData, {}, this);

  this.dirtyCheck = ko.computed({
    read: function() {
      if (!self.isDirty){ //property doesn't exist yet
        var json = ko.toJSON(self); //trigger a subscription to all observable properties.
      } else {
        self.isDirty(true); //If this is being evaluated then by definition something has changed.
      }
      return;
    }
  });
  this.isDirty = ko.observable(false); //only add the property after the computed has been initialized
}