在knockoutjs上下文中使用ajax转移结果

时间:2013-09-04 20:47:15

标签: javascript jquery ajax knockout.js

我有这段代码(见下文)。用Firebug调试和观察它告诉我,我在“.done”函数中得到了我想要的数据。我的self.Task正是我想要的。然而,事情正在发生

ViewModel = function(serviceClient) {
...

serviceClient.getTasks(projectId)
        .done(function (data) {

            self.Tasks = ko.observableArray(
                ko.utils.arrayMap(data, function (item) {
                   return new TaskViewModel(item);
               }));

            alert("Inner result: " + self.Tasks().length + " task(s)");
        })

    alert("Outer result " + self.Tasks().length + " task(s)");

...
}

,其中

serviceClient.getTasks = function (param) {
        console.log("Get Model from Service");
        return $.ajax({
            type: "GET",
            url: serviceRoot + "GetAllTasks",
            beforeSend: serviceFramework.setModuleHeaders,
            data: "projectid=" + param,
            cache: false
        });
    };

为什么INNER结果和OUTER结果不同?

2 个答案:

答案 0 :(得分:0)

你在你的ajax中尝试过成功活动了吗?您可以在此事件处理程序中执行所有数组映射

答案 1 :(得分:0)

您的主要问题是在“外部”警报执行之前您的ajax呼叫未完成。考虑做类似的事情:

var request = serviceClient.getTasks(projectID).done(function(data) {
  alert("Inner: " + data.length);
});
// ... more code ...
request.done(function(data) {
  alert("Outer: " + data.length);
});

当然,这对我来说似乎有些愚蠢。像第二个警报一样的感觉应该只在第一个.done处理程序中。这相当于:

serviceClient.getTasks(...).done(function(data) {
  alert("Inner");
  alert("Outer");
});

不好:http://jsfiddle.net/bqsjm/

一个解决方案:http://jsfiddle.net/bqsjm/1/

您需要优雅地传递ajax返回的promise对象,或者在设置.done后执行的self.Tasks函数内添加函数调用

说到这一点,当你写作时,你是从DOM中孤立self.Tasks

self.Tasks = ko.observableArray(...arrayMap...);

我想你打算写:

self.Tasks(...arrayMap...);

考虑:

// DOM
<span data-bind="text: $root.foo"></span>

// Javascript land
var vm = { foo: ko.observable("foo") };
ko.applyBindings(vm);
// <span> tag will read "foo"
vm.foo = ko.observable("bar");// orphaned
// <span> tag still reads "foo"

希望有所帮助。