Knockout SmartTag实施细节

时间:2014-10-16 22:38:24

标签: knockout.js

我希望在我遇到的其中一个链接中了解更多关于智能脏标签实现的信息。

<ul data-bind="foreach: items">
<li data-bind="css: { dirty: dirtyFlag.isDirty }">
    <span data-bind="text: id"></span>
    <input data-bind="value: name" />
</li>

ko.dirtyFlag = function(root) {
    var result = function() {}
    var   _initialState = ko.observable(ko.toJSON(root));

    result.isDirty = ko.computed(function() {
        return  _initialState() !== ko.toJSON(root);
    });

    return result;
};


function Item(id, name) {
    this.id = ko.observable(id);
    this.name = ko.observable(name);
    this.dirtyFlag = new ko.dirtyFlag(this);
}

var ViewModel = function(items) {
    this.items = ko.observableArray([
        new Item(1, "one"),
        new Item(2, "two"),
        new Item(3, "three")
    ]);

    this.save = function() {
        alert("Sending changes to server: " + ko.toJSON(this.dirtyItems));  
    };

    this.dirtyItems = ko.computed(function() {
        return ko.utils.arrayFilter(this.items(), function(item) {
            return item.dirtyFlag.isDirty();
        });
    }, this);

    this.isDirty = ko.computed(function() {
        return this.dirtyItems().length > 0;
    }, this);
};

ko.applyBindings(new ViewModel());

我对原post

进行了一些更改

这是我的新fiddle 我想更多地了解创建单独的函数对象ko.dirtyFlag的原因。 博客文章说

  

使对象成为函数并将计算的observable添加到函数对象中。这意味着你必须以dirtyFlag.isDirty()绑定它。当ko.toJS运行时,它只会看到一个普通函数并忽略它。

这实际意味着什么?

    _initialState = ko.observable(ko.toJSON(root))

ko.dirtyFlag中的这个语句是否也会重新评估对象创建者中的所有可观察对象,即Item?

另外,_initialState真正需要成为一个可观察的吗?

_initialState = ko.observable(ko.toJSON(root)) 如果_initialState不是可观察的,则执行失败。

关于以这种方式构造代码的实际原因的简要说明是我真正想知道的。

1 个答案:

答案 0 :(得分:0)

使对象成为函数并将计算的observable添加到函数对象中。这意味着你必须以dirtyFlag.isDirty()绑定它。当ko.toJS运行时,它只会看到一个普通函数并忽略它。

这实际意味着什么?

  • 这意味着通过使其成为一个功能,它将不会包含在我们将发送给服务器的信息中。这将有助于我们不向服务器发送大量不必要的数据,因为Server可能不关心IsDirty的东西。它与jS忽略所有可观察的相关信息的方式相同,只是给你一个对象的简单副本。

    _initialState = ko.observable(ko.toJSON(root));

ko.dirtyFlag中的这个语句是否也会重新评估对象创建者中的所有可观察对象,即Item?

  • 不,它只会在实际的属性/对象上执行此操作,在本例中为ITEM。我知道名字param“root”令人困惑,但它不是整个ViewModel。

另外,_initialState真正需要成为一个可观察的吗?

  • 如果你看到实际的imprementation,isDirty标志是一个基于initialState的计算的propety。

    result.isDirty = ko.computed(function(){         return _isInitiallyDirty()|| _initialState()!== ko.toJSON(root);     });

    如果它没有成为可观察对象,则每次对象更改时都不会评估isDirty。

希望这是有道理的。