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

时间:2013-12-08 21:00:26

标签: javascript knockout.js

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

我有一个按钮(删除输入),其中包含在可观察数组包含2个以上项目时返回的enable和css绑定。

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

我还有一个函数(loadIntegerSorter),它将observable数组设置为包含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();
    }
}

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

我链接到的小提琴并没有完全证明这个问题,因为它取决于发出真正的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调用有关。

2 个答案:

答案 0 :(得分:1)

1)

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

self.isLoading(true);

哪个收益

  

TypeError:'undefined'不是一个函数(评估   'self.isLoading(真)')

告诉您self.isLoading未在代码中的任何位置声明。这甚至会在发送ajax请求之前中断代码执行。


2)

与1相同)但这次是self.msgbox.status()。未申报:将破坏您的代码。


3)

函数self.loadIntegerSorter在成功函数中显示为self.loadSortedIntegers。此外,self.save函数显示两次。第二个会淘汰第一个,但我想第一个就是那个小提琴。


4)

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

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


5)

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

执行此操作,然后使用this.loadSortedIntegers()更改成功功能内容。


我冒昧地对你的小提琴做了一些修改。花点时间检查差异here并运行它here

答案 1 :(得分:0)

尝试使用valueHasMutated直接推送observable更新:

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

};