Javascript 在Knockout.js和Knockout.mapping.js中使用脏标志或撤消堆栈

Javascript 在Knockout.js和Knockout.mapping.js中使用脏标志或撤消堆栈,javascript,knockout.js,knockout-mapping-plugin,undo,kolite,Javascript,Knockout.js,Knockout Mapping Plugin,Undo,Kolite,我正在尝试创建或使用现有的dirtyFlag。然而,我看到的所有示例都没有谈到如何将它们与knockout.mapping.js插件集成 有很多非常好的例子,比如Ryan Niemeyer的东西和John Papa的KoLite,但是它们都不能回答这个简单的问题 “我的viewModel上有很多属性,我没有时间手工编码 应该由敲除映射插件处理的内容” 我觉得这是一个肮脏的(没有双关语的意思)小秘密,需要泄露出去 谢谢 年轻,我感觉到你的痛苦。我在ko github网站上偶然发现了这一点 其概念是

我正在尝试创建或使用现有的
dirtyFlag
。然而,我看到的所有示例都没有谈到如何将它们与knockout.mapping.js插件集成

有很多非常好的例子,比如Ryan Niemeyer的东西和John Papa的KoLite,但是它们都不能回答这个简单的问题

“我的viewModel上有很多属性,我没有时间手工编码 应该由敲除映射插件处理的内容”

我觉得这是一个肮脏的(没有双关语的意思)小秘密,需要泄露出去


谢谢

年轻,我感觉到你的痛苦。我在ko github网站上偶然发现了这一点

其概念是创建一个changetracker函数,并将其分配为虚拟机上的道具

function changeTracker(objectToTrack, hashFunction) {    
hashFunction = hashFunction || ko.toJSON;
var lastCleanState = ko.observable(hashFunction(objectToTrack));

var result = {
    somethingHasChanged : ko.dependentObservable(function() {
        return hashFunction(objectToTrack) != lastCleanState()
    }),
    markCurrentStateAsClean : function() {
        lastCleanState(hashFunction(objectToTrack));   
    }
};

return function() { return result }
}
var viewModel = {someTextProperty: ko.observable("Hello"), boolProperty: ko.observable(false),
arrayItems: ko.observableArray([]),

addItem : function() { this.arrayItems.push("Another") }
};
viewModel.tracker = new changeTracker(viewModel);
ko.applyBindings(viewModel);
您仍然需要设置跟踪器,但在使用ko映射时也应该能够实现这一点

这似乎有点难看,但这个概念可以为更好的解决方案而建立,而不是没有。
希望这有帮助

我不是淘汰库专家,但我非常喜欢简单的解决方案。KoLite中的John Papa和Hans Fjallemarks解决方案:对于viewmodel中的所有或选定观测值,是一个简单但最有效的脏旗的优秀解决方案

我对它做了一些调整,包括撤销

ko.DirtyFlag = function (objectToTrack, isInitiallyDirty, hashFunction) {

    hashFunction = hashFunction || ko.toJSON;

    var
        self = this,
        _objectToTrack = objectToTrack,
        _lastCleanState = ko.observable(hashFunction(_objectToTrack)),
        _isInitiallyDirty = ko.observable(isInitiallyDirty),

        result = function () {
            self.forceDirty = function () {
                _isInitiallyDirty(true);
            };

            self.isDirty = ko.computed(function () {
                return _isInitiallyDirty() || hashFunction(_objectToTrack) !== _lastCleanState();
            });

            self.reset = function () {
                _lastCleanState(hashFunction(_objectToTrack));
                _isInitiallyDirty(false);
            };

            self.undo = function () {
                var source = JSON.parse(_lastCleanState());
                for (prop in source) {
                    if (_objectToTrack[prop]() && _objectToTrack[prop]() != source[prop]) {
                        _objectToTrack[prop](source[prop]);
                    }
                }
                _isInitiallyDirty(false);
            };
            return self;
        };

    return result;
};
“我不想用这么多属性手工编写视图模型”

我想在上面加上这个作为评论,但是声誉限制

使用“创建”自定义对象构造

如果您想自己处理映射的一部分,还可以提供create回调。如果存在此回调,映射插件将允许您自己进行这部分映射


因此,当服务器通过映射插件时,使用自定义计算的obervable等扩展来自服务器的数据。

仍然不确定这是如何回答我的OP的。我希望自动将脏标志和/或撤消添加到我的所有可观察属性(想想数百)中。我不想用这么多的属性(可能会随着时间的推移而改变)手工编写视图模型。因此,我再次寻找一种更“自动”或“击倒.映射”的方法来实现这一点。
var mapping = {
    'children': {
    create: function(options) {
            var newChild = new myChildModel(options.data);
            newChild.dirtyFlag = 'add computed here';
            newChild.changeTracker = 'setup some change tracking or whatever';
            return newChild;
        }
    }
}
var viewModel = ko.mapping.fromJS(data, mapping);