3

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

有很多非常棒的例子,比如 Ryan Niemeyer 的东西和 John Papa 的 KoLite,但他们都没有回答这个简单的问题

“我的 viewModel 上有很多属性,我没有时间手动编码应该由淘汰映射插件处理的东西”

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

谢谢!

4

3 回答 3

3

我不是淘汰库的专家,但我非常喜欢简单的解决方案。KoLite 中的 John Papa 和 Hans Fjallemarks 解决方案:https ://github.com/CodeSeven/kolite是一个出色的解决方案,用于在视图模型中的所有或选定的 observable 上设置简单但最有效的脏标志。

我对其进行了一些调整以包括撤消。

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;
};
于 2013-12-11T11:21:42.013 回答
1

“我不想手动编写具有这么多属性的视图模型”

我会将其添加为上面的评论,但声誉限制......

http://knockoutjs.com/documentation/plugins-mapping.html

使用“create”自定义对象构造</p>

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

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);

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

于 2014-08-05T23:25:23.570 回答
0

年轻人,我感受到了你的痛苦。我在 ko github 网站https://github.com/knockout/knockout/wiki/Dirty-Tracking上偶然发现了这个http://jsfiddle.net/b3ky5/

这个概念是创建一个 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 映射时也应该能够完成此操作。

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

于 2013-11-18T20:49:49.050 回答