当通过Ajax成功回调更新可观察数组时,启用绑定中断

Enable binding breaks when observable array updated via Ajax success callback

本文关键字:数组 启用 中断 绑定 观察 Ajax 成功 更新 回调      更新时间:2024-04-27

http://jsfiddle.net/FZ6K6/24/

我有一个带有enable和css绑定的按钮(Remove-inputs),当一个可观察数组包含2个以上的项时,会返回这些绑定。

<button data-bind="click: removeInput, enable: Integers().length >2, css { red: Integers().length >2 }">Remove Input</button>

我还有一个函数(loadIntegerSorter),它将可观察数组设置为包含2个项。

self.loadIntegerSorter = function () {
    self.Integers([new integer(0, 0, 0), new integer(0, 0, 0)]);
};

我还有一个通过ajax提交的保存函数。在成功回调中,将调用loadIntegerSorter。

success: function (result) {
    if (result.Status == "success") {
        isvm.loadSortedIntegers();
    }
}

然而,这似乎打破了启用绑定。当数组项为2时,CSS绑定的行为与预期一致。但启用绑定不会。我可以在Ajax函数之外成功地运行loadIntegerSorter,所以我认为这是一个同步问题,但我不知道解决方案是什么

我链接到的fiddle并没有完全说明这个问题,因为它取决于是否发出真正的Ajax请求。但我希望它能显示出足够的理解力。

细化:

这导致启用绑定的预期行为:

self.save = function () {
    self.isloading();
};

但事实并非如此:

self.save = function () {
    $.ajax("/Home/Index", {
        data: ko.toJSON(self.integerSorter),
        cache: false,
        type: "post",
        contentType: "application/json",
        context: self,
        success: function (result) {
            this.isloading();
        }
    });
};

这也不是:

self.save = function () {
    self.isloading();
    $.ajax("/Home/Index", {
        data: ko.toJSON(self.integerSorter),
        cache: false,
        type: "post",
        contentType: "application/json",
        context: self,
        success: function (result) {
        }
    });
};

无论问题的原因是什么,似乎都与ajax调用有关。

1)

在您的self.save函数内部,您正在调用

self.isLoading(true);

产生

TypeError:"undefined"不是函数(正在求值'self.isLoading(true)')

告诉您CCD_ 2没有在代码中的任何位置声明。这甚至会在发送ajax请求之前中断代码执行。


2)

与1相同),但这次是针对self.msgbox.status()。未声明:将破坏您的代码。


3)

函数self.loadIntegerSorter在成功函数中显示为self.loadSortedIntegers。此外,self.save函数出现并声明了两次。第二个会超过第一个,但我想第一个就在那里。


4)

在成功函数内部,result.Status没有任何意义。您必须理解result只是一个纯文本字符串,访问字符串的Status属性将导致错误。也许您希望响应是一个具有Status属性的JSON对象?如果是这种情况,您必须自己(JSON.parse(response))或告诉jQuery为您反序列化字符串(用$.getJSON替换$.ajax)。

然而,也可能是您没有收到任何JSON回复,只是想访问响应状态,假设您可以这样做。你不能。在成功功能中,您已经知道您的请求已成功发送并收到响应。无需再次检查。


5)

您正在对变量isvm调用loadSortedIntegers()方法。这是一种完全错误的方法,即使它现在应该起作用,也可能在未来引发巨大的麻烦。isvm是一个全局变量,用于包含viewModel的实例。success函数包含在viewModel本身中,您应该使用thisself访问它自己的方法。类不应使用全局变量访问其自身的实例。问题:如何使this和/或self.isLoading0在成功功能中可用?可以通过将上下文属性设置为$.ajax对象来访问this。正如你写success: function(){}一样,你应该在那之前写context: this,或者在你的情况下,写context: self

这样做,然后用this.loadSortedIntegers()更改成功函数的内容。


我冒昧地对你的小提琴做了一些修改。请慢慢来检查这里的差异,并在这里运行它。

尝试使用valueHasMuted直接推送可观察到的更新:

self.loadIntegerSorter = function () {
    self.Integers([new integer(0, 0, 0), new integer(0, 0, 0)]);
    self.Integers.valueHasMutated();
};