【问题标题】:Knockout Mapping Object Not Returned by Durandal ViewmodelDurandal Viewmodel 未返回 Knockout 映射对象
【发布时间】:2015-03-29 15:26:18
【问题描述】:

我打算使用 Knockout Mapping 插件将 ajax 调用返回的数据映射到 Durandal 框架下的视图模型。但是,我不知道如何返回映射对象以便视图可以使用它。这是我的视图模型 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,我将其返回给视图。但是,当我在 Web Inspector 下检查 'viewmodels/login' 返回的 loginInterfaceData 对象时,它是一个空对象。我能想到的唯一原因是视图模型在映射完成之前返回 loginInterfaceData。但是,我不知道如何防止这种情况发生。

任何想法/建议将不胜感激。提前致谢!

【问题讨论】:

    标签: javascript mvvm knockout.js durandal


    【解决方案1】:

    发生这种情况是因为您返回了对内部 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

    【讨论】:

      【解决方案2】:

      显然问题在于在调用activate 函数之前返回loginInterfaceData 对象,导致视图接收到原始的空对象。我的解决方案最终是先将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
      

      希望这对遇到与我相同问题的人有所帮助。干杯。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-23
        • 2018-05-30
        • 2021-02-17
        • 2012-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-17
        相关资源
        最近更新 更多