1

我已经看遍了,并不能真正找到一个优雅的解决方案来解决我的问题......

<div class="viewPerson">
     <strong>Name:</strong> <span data-bind="text: Person.Name"></span>
</div>

<div class="editPerson">
    <strong>Name:</strong> <input type="text" data-bind="value: Person.Name">  </span>
    <input type="submit" value="Save" data-bind="click: Save" />
</div>

我在同一字段(名称)的页面(Knockout 2.2.1)上有两个数据绑定,一个在我的“View Div”中,一个在我的“Edit Div”中。有没有一种简单的方法可以让我说在“View Div”被保存回数据库之前不要更新它。

这是 jsfiddle http://jsfiddle.net/NoseBagUK/bvw4j/3/中的一个示例

到目前为止,我最好的方法是拥有 Person 对象的两个副本,一旦 ajax 魔法发生,我就有了一个同步两个 Person 对象的函数。像这样.. http://jsfiddle.net/NoseBagUK/jjK4j/1/

非常感谢任何帮助。

菲尔

4

1 回答 1

7

我实际上建议您立即更新视图模型并在 ajax 调用失败时撤消该更改。它会让你的应用看起来更快——因为 90% 以上的 ajax 调用都有望成功,所以为 10% 的情况编写代码是没有意义的。

编辑:我强烈推荐这个视频。它出色地支持了这一点。

但这是如何做到的:

这一切的本质是computed对你的拦截originalObservable

ko.computed({
    read: function() {
        return originalObservable();
    },
    write: function( newVal ) {
        // perform ajax call
        $.post( '<url>' , { data: originalObservable() } , function() {
            // in your success callback
            // update your observable
            originalObservable( newVal );
        });
        // note: we get to this point without updating the originalObservable
        //       because this is part of the synchronous code
        //       where as the ajax call will, of course, be asynchronous
    }
});

您可以使用许多不同的方式:

-1- 在您的视图模型上作为单独的属性并将您的编辑 html 绑定到此

function Viewmodel() {
    this.original = ko.observable();
    this.editable: ko.computed( /* as above */ );
}

-2- (1) 的轻微变化,但更简洁,是将计算结果放在可观察对象上作为属性:

function Viewmodel() {
    this.original = ko.observable();
    this.original.editable: ko.computed( /* as above */ );
}

-3- 创建一个自定义绑定,为您创建这个计算,让您的视图模型更加干净:

ko.bindingHandlers.myAjaxSave = {
    init: function( element, valueAccessor ) {
        var originalObservable = valueAccessor();
        var editable = ko.computed({
            read: function() {
                return originalObservable();
            },
            write: function( newVal ) {
                // perform ajax call
                $.post( '<url>' , { data: originalObservable() } , function() {
                    // in your success callback
                    // update your observable
                    originalObservable( newVal );
                });
                // note: we get to this point without updating the originalObservable
                //       because this is part of the synchronous code
                //       where as the ajax call will, of course, be asynchronous
            }
        });

        // this applies the binding to the HTML element
        ko.applyBindingToNode( element , {
            value: editable
        });
    }
}

您现在可以在输入 HTML 元素中使用它,例如:

<input data-bind="myAjaxSave: Person.Name" />
于 2013-05-17T12:02:46.933 回答