在覆盖backbone.js中的同步功能时,如何处理服务器响应

时间:2012-04-13 15:14:19

标签: javascript backbone.js

我一直在尝试将我的backbone.js应用程序连接到现有的Codeigniter API。我查看了github上的todos示例,并从那里建立起来。 我正在覆盖findAll函数,该函数在'read'上调用,我试图获取页面并将它们返回给fetch函数:

findAll:function(){     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输出(“响应”,响应):

{
    "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”])打印出“undefined”。为什么这样做?

提前多多感谢!

-------------------- edit ---------------------

感谢您的回答。我可以在模型中执行ajax调用的提示非常有用。问题是我试图将几个页面放到一个PageList Collection中:

$(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 intitialize函数中我正在调用

Pages.fetch();

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

3 个答案:

答案 0 :(得分: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调用中从success函数返回一些东西,它会直接进入bitbucket。那个_.values()不会去任何地方。来自$ .ajax()调用的是一个承诺,就是这样。该承诺后来可以附加.done(),. fail()等,它也可以与.when()一起使用,并用于其他目的。但是,它与稍后调用的成功函数无关。这相当于附加到该承诺的.done()函数。

我的猜测是你真正想要的是AJAX完成然后操纵结果然后在模型上设置它们。

一般来说,尝试强制Backbone同步并不是它的意思。即使你不打算使用Backbone内置的Sync并跳过fetch,save等,它仍然很乐意接受这样的调用(并注意模型只会在更新时更新,就像你正在做的那样获取):

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

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

答案 1 :(得分:1)

尝试在PageList Backbone Collection中添加它:

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

这有两件事:

  1. 使用.pages引用您的回复中的pages数组。从我的代码中可以看出,骨干网正在使用整体对象响应来确定集合中的对象。
  2. 告诉主干使用pages数组来实例化集合中的模型。它通过覆盖原生parse方法并返回您真正想要的内容(页面数组)来实现此目的。
  3. 执行此操作应该将您的页面对象放入一个PageList集合中。在类似的情况下,这对我有用。希望它有所帮助!

答案 2 :(得分:0)

好的,所以我弄清楚这里究竟出了什么问题。正如John Munsch在第一个答案中提到的那样,ajax请求并不完全正确。这实际上不是主干的问题,而是我正在制作的ajax调用。首先,我将其更改为json,其次我在ajax调用之外创建了一个变量'pages',它可以记住响应并将其返回到synch函数:

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;

},

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