我打算使用Knockout Mapping插件将从ajax调用返回的数据映射到Durandal框架下的viewmodel。但是,我不知道如何返回映射对象,以便视图可以使用它。这是我的viewmodel login.js代码:
define(function (require) {
var system = require('durandal/system'),
app = require('durandal/app'),
ko = require('knockout'),
komapping = require('komapping'),
deferred = $.Deferred(),
loginOptionsUrl = '/json/loginOptions.json',
loginInterfaceData = {};
ko.mapping = komapping;
return {
activate: function(){
var request = $.getJSON(loginOptionsUrl)
.done(function(data){
loginInterfaceData = ko.mapping.fromJS(data);
system.log(loginInterfaceData); //Do a check here; loginInterfaceData contains all the right data
deferred.resolve();
});
return deferred.promise();
},
loginInterfaceData: loginInterfaceData; //However, the view gets an empty object
如您所见,从ko.mapping返回的对象被分配给loginInterfaceData,我将返回到视图。但是,当我检查' viewmodels / login'返回的loginInterfaceData对象时在Web Inspector下,它是一个空对象。我能想到的唯一原因是viewmodel在映射完成之前返回loginInterfaceData。但是,我不知道如何防止这种情况发生。
任何想法/建议都将受到最高的赞赏。提前致谢!
答案 0 :(得分:0)
这是因为您返回对内部loginInterfaceData
的引用,但在您的activate
函数中重新分配该变量,因此之前返回的loginInterfaceData
始终是一个空对象。您可以做的是为loginInterfaceData
返回一个getter函数,如下所示:
...
getLoginInterfaceData: function() {
return loginInterfaceData;
}
...
在您的通话代码中,activate
完成后,只需拨打getLoginInterfaceData()
这是一个简单的例子:
function foo() {
var bar = {};
return {
setBar : function(x) {
bar = x;
},
bar: bar,
getBar: function() {
return bar;
}
}
}
var f = foo();
f.setBar(5);
console.log(f.bar); // logs empty object
console.log(f.getBar()); // logs value of inner foo.bar

答案 1 :(得分:0)
显然问题在于在调用loginInterfaceData
函数之前返回activate
对象,导致视图接收原始的空对象。我的解决方案最终是首先将loginInterfaceData
绑定到空数据,然后在通过Ajax接收数据后更新它。像这样:
(...)
ko.mapping = komapping;
loginInterfaceData = ko.mapping.fromJS({}); //instead of assigning loginInterfaceData = {}, I use KO Mapping with an ampty JSON object
(...)
return {
activate: function(){
return $.ajax({
url: loginOptionsUrl,
contentType: 'application/json',
}).done(function(data) {
ko.mapping.fromJS(data, loginInterfaceData);//so here, instead of mapping for the first time, I remap/update it
});
},
loginInterfaceData: loginInterfaceData; //at this point, loginInterfaceData is still empty object but will be updated/remap once ajax call is successful
希望这可以帮助遇到与我相同问题的人。欢呼声。