【问题标题】:How do I deal with server response when overriding the sync function in backbone.js覆盖backbone.js中的同步功能时如何处理服务器响应
【发布时间】:2012-04-25 23:27:11
【问题描述】:

我一直在尝试将我的主干.js 应用程序连接到现有的 Codeigniter API。我查看了 github 上的 todos 示例并从那里开始构建。 我正在重写 findAll 函数,该函数在“读取”时调用,并试图获取页面并将它们返回给 fetch 函数:

findAll: 函数() { console.log('synch - findAll');

var url = "/folio/get/8";
var data = ''; 

var postmethod = 'GET';

$.ajax({
    url : url,
    type : postmethod,
    async: false,
    data: data,
    success: function(response) 
    {
                    console.debug("response",response);
        console.debug("response.pages", response["pages"]);
        return _.values(response["pages"]);
    }
});

}

API 返回类似这样的内容 - 通过 console.debug("response", response) 输出:

{
    "id": "8",
    "facebook_id": "123456789",
    "title": "title",
    "access_date": null,
    "rating_avg": "0",
    "pages": [
        {
            "id": "6",
            "picture1": {
                "id": "3",
                "tag": "1",
                "tip": "Crazy",
                "facebook_picture_id": "1239102391023"
            },
            "picture2": "28",
            "picture3": "29",
            "picture4": null,
            "picture5": null,
            "picture6": null,
            "caption1": "caption 1",
            "caption2": "caption 2",
            "sequence": "2",
            "folio": "8",
            "ts": "2012-04-10 15:13:23",
            "template": "#page-template-2"
        },
        {
            "id": "5",
            "picture1": "24",
            "picture2": "25",
            "picture3": "26",
            "picture4": null,
            "picture5": null,
            "picture6": null,
            "caption1": "caption 1",
            "caption2": "caption 2",
            "sequence": "4",
            "folio": "8",
            "ts": "2012-04-10 15:13:23",
            "template": "#page-template-2"
        }
    ]
}

但随后 console.debug("response.pages", response["pages"]) 打印出“未定义”。为什么会这样?

提前非常感谢!

-------------------- 编辑 ---------

感谢您的回答。我可以在模型中进行 ajax 调用的技巧真的很有帮助。问题是我正在尝试将多个页面放入一个 PageList 集合中:

$(function(){
  // Page Collection
  // ---------------

  var PageList = Backbone.Collection.extend({

    model: Page,
    localStorage: new Store("wickes-backbone"), // this to get hold of my overwritten localstorage file - it is not actually a localStorage

    nextOrder: function() {
      if (!this.length) return 1;
      return this.last().get('order') + 1;
    },

    comparator: function(page) {
      return page.get('order');
    }

  });

  window.Pages = new PageList;
});

所以在我正在调用的 appview 初始化函数中

Pages.fetch();

填充所有页面并更新视图。我不确定如何在模型本身中做到这一点?

【问题讨论】:

  • 你能发布你的视图/模型吗?
  • 将代码更改为:console.debug("response.pages", response.pages);控制台打印:response.pages undefined 所以没有不同的结果

标签: javascript backbone.js


【解决方案1】:

我认为你的问题是你如何在 $.ajax() 中使用成功函数:

$.ajax({
    url : url,
    type : postmethod,
    async: false,
    data: data,
    success: function(response) 
    {
        console.debug("response",response);
        console.debug("response.pages", response["pages"]);
        return _.values(response["pages"]);
    }
});

如果您在 AJAX 调用的成功函数中返回某些内容,它会直接进入 bitbucket。那 _.values() 没有前往任何地方。 $.ajax() 调用的结果是一个承诺,仅此而已。该 promise 可以在稍后附加 .done()、.fail() 等,它也可以与 .when() 一起使用以及用于其他目的。但是,它与稍后将调用的成功函数无关。这相当于只是一个附加到该承诺的 .done() 函数。

我的猜测是,您真正想要的是让 AJAX 完成,然后操纵结果,然后将它们设置到模型上。

一般来说,试图强制 Backbone 同步并不是它的本意。即使您不打算使用 Backbone 中内置的 Sync 并跳过获取、保存等。它仍然很乐意像这样被调用(请注意,模型会在更新时更新,就像您在做获取):

var myModel = Backbone.Model.extend({
  goGetSomeData : function () {
    var scope = this;

    $.ajax(....).done(
      function (results) {
        scope.set(results);
      }
    );
  }
});

【讨论】:

  • 非常感谢您的回答,可以直接在模型内与服务器通信的建议非常有帮助。但是我需要同时更新几个模型,并且不知道如何在没有同步功能的情况下做到这一点。我编辑了上面的问题。如果您能再看一眼,我将非常感激。
【解决方案2】:

尝试将其添加到您的 PageList Backbone 集合中:

  parse: function(response) {
    return response.pages
  }

这做了两件事:

  1. 使用.pages 在您的响应中引用pages 数组。从您的代码中我可以看出,主干使用整体对象响应来确定您集合中的对象。
  2. 告诉主干使用pages 数组来实例化集合中的模型。它通过覆盖原生 parse 方法并返回您真正想要的(页面数组)来实现这一点

这样做应该将您的页面对象放入一个 PageList 集合中。在类似的情况下,这对我有用。希望对您有所帮助!

【讨论】:

    【解决方案3】:

    好的,所以我找出了这里实际出了什么问题。正如 John Munsch 在第一个答案中提到的,ajax 请求不太正确。这实际上不是骨干网的问题,而是我正在进行的 ajax 调用。首先,我将其更改为 json,其次我在 ajax 调用之外创建了一个变量“pages”,它可以记住响应并将其返回给同步函数:

    findAll: function() {
    
        var url = "/folio/get/8";
        var pages;
        var postmethod = 'GET';
    
        $.ajax({
             type: postmethod,
             url: url,
             async: false,
             beforeSend: function(x) {
              if(x && x.overrideMimeType) {
               x.overrideMimeType("application/j-son;charset=UTF-8");
              }
         },
         dataType: "json",
         success: function(data){
             console.debug("data", data);
             console.debug("data.pages", data.pages);
             pages = data.pages;
    
         }
        });
    
        return pages;
    
    },
    

    非常感谢大家的帮助,从你们的回答中我学到了很多!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-22
      • 1970-01-01
      • 1970-01-01
      • 2013-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多