【问题标题】:Using jquery ajax with knockout.js mapping plugin将 jquery ajax 与 knockout.js 映射插件一起使用
【发布时间】:2015-04-18 12:41:32
【问题描述】:

我正在尝试将 jquery 的 $.ajax 函数与 knockout.js 映射插件一起使用,此处使用测试 api:http://rest.learncode.academy/

返回的数据格式不正确。我的 js 看起来像这样:

    function FromDb(){

             $.ajax({
              type: 'GET',
              url: 'http://rest.learncode.academy/api/johnbob/friends',
              //dataType: "json",
              success: function(data) {
                console.log("I have friends!", data[0]); //returns all of johnbob's friends
                myResult = data[0];
            return myResult
                }
            });



//return{ name: 'test' }

    }


    function MaptoKo(frnd){
        var map = ko.mapping.fromJS(frnd);
        return map;
    }

    var obj={
        friends:ko.observable(new MaptoKo(new FromDb())),
    }

    ko.applyBindings(obj.friends);

因为 api 返回一个数组,我只需要一个对象,我使用 data[0] 来获取数组中的第一项。当我注释掉 ajax 调用并取消注释 //return{ name: 'test' } 时,我得到了我想要的结果,我只是不确定为什么它不能使用 ajax 调用。

【问题讨论】:

    标签: jquery ajax knockout.js knockout-mapping-plugin


    【解决方案1】:

    我花了几分钟来记住如何以正确的方式执行此操作,即从 AJAX 成功回调函数内部更新您的绑定。

    问题是对FromDb() 的调用和AJAX success 函数之间的断开连接。从成功函数返回值是异步发生的,这意味着代码无法知道将返回的值挂钩到MaptoKo(new FromDb()) 调用中。当您只调用return { name: 'test' }; 时,FromDb() 会发生同步,因此结果确实会进入MaptoKo 函数。

    $.getJSON("/some/url", function(data) { 
        // Now use this data to update your view models, 
        // and Knockout will update your UI automatically 
    })
    

    所以,Knockout 需要帮助您做的就是:...

    • 对于加载,请使用您使用上述技术之一收到的数据更新您的视图模型

    来源:Knockout JSON Data Docs

    对于您的特定代码,这意味着如下:

    function FriendsViewModel() {
        var self = this;
        self.friends = ko.observable();
    
        // Load the initial data
        $.ajax({
            type: 'GET',
            url: 'http://rest.learncode.academy/api/johnbob/friends',
            //dataType: "json",
            success: function(data) {
                //returns all of johnbob's friends
                console.log("I have friends!", data[0]);
                myResult = data[0];
                // Don't return the result, bind it to the viewmodel
                self.friends(myResult);
              }
          });
    }
    
    ko.applyBindings(new FriendsViewModel());
    

    Loading and Saving tutorial 对此进行了很好的介绍。请注意,这不再真正使用映射插件。为了配合,请遵循mapping plugin docs 的建议:

    要通过映射插件创建视图模型,请将上面代码中创建的viewModel替换为ko.mapping.fromJS函数:

    var viewModel = ko.mapping.fromJS(data);
    

    这会自动为数据的每个属性创建可观察的属性。然后,每次从服务器接收到新数据时,您都可以通过再次调用ko.mapping.fromJS 函数来一步更新视图模型上的所有属性:

    // Every time data is received from the server:
    ko.mapping.fromJS(data, viewModel);
    
    $.(function (){
    
        // Load the initial data
        $.ajax({
            type: 'GET',
            url: 'http://rest.learncode.academy/api/johnbob/friends',
            //dataType: "json",
            success: function(data) {
                //returns all of johnbob's friends
                console.log("I have friends!", data[0]);
                myResult = data[0];
                // Don't return the result, bind it to the viewmodel
                var viewModel = ko.mapping.fromJS(myResult);
                // Only bind once after the initial load.
                // If you save or reload data, don't reapply bindings
                ko.applyBindings(viewModel);
              }
          });
    });
    

    最后一个例子只是一个猜测,我自己从未使用过映射插件。但希望它说明您不能只从异步回调中返回结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-28
      • 1970-01-01
      • 2014-03-06
      • 1970-01-01
      • 2016-01-25
      • 2013-01-07
      相关资源
      最近更新 更多