jQuery,backbone和fetch - 等待完成?

时间:2015-02-17 02:21:25

标签: jquery backbone.js asynchronous wait

我有一个BackboneJS的问题,我有一个正在提取的集合。集合提取会触发其中所有模型的提取,但模型的提取(或初始化,选择)是一个自定义的jQuery调用

fetch: function(options) {
    $.getJSON('/my/uri/').success(function(data) {
        processData(data);
    });
}

问题是集合事件挂钩在加载和处理集合中的所有模型之前呈现我的数据(因为getJSON是异步的)。我可以看到如何用一个模型做到这一点;我发现了一些使用延迟变量的引用。这里建议的方法是什么?

3 个答案:

答案 0 :(得分:1)

您在fetch中所做的只是加载JSON文件并将其传递到其他地方。这不是fetch所代表的。 如果您想自己获取,则应将(reset)数据设置到您的集合中并触发eventlistener的事件。

fetch: function(options) {
    $.getJSON('/my/uri/').success(function(data) {
        _result = doSomethingForTheData(data);
        //this makes reset event
        yourCollection.reset(_result);
        //or you can make your custom event whatever you want.
        yourCollection.reset(_result,{silent : true});
        yourcollection.trigger("yourCustomEventName",yourCollection);
    });
}

但我认为你想要实现的目标并不需要覆盖fetch

在你的收藏中

var YourCollection = Backbone.Collection.extend({
   url: 'my/uri'
});
在您的视图中

yourCollection = new YourCollection();
yourCollection.fetch()
yourView.listenTo(yourCollection,"sync",function(){
  this.refresh()
  //or whatever you want with your updated Collection.
});

您也可以使用AJAX的成功回调来处理异步工作的方法,就像您尝试的那样。但是没有理由不使用Backbone松散耦合结构(事件触发/侦听)。

答案 1 :(得分:0)

Backbone-y这样做的方法是让Model提供"parse" function。该函数从服务器接收原始响应以进行进一步处理。我认为在processData(...)中你需要做的任何事情都可以在那里完成。假设你这样做,你应该能够信任Backbone来做正确的事情,将修改后的响应作为属性提供给模型。

所以你的模型&收集可能看起来像:

var MyModel = Backbone.Model.extend({
    parse: function(response) {
        // Do what you need to modify
        var modified = modifyResponse(response);
        return modified;
    },

    // ... whatever else you need
});

var MyCollection = Backbone.Collection.extend({
     model: MyModel,

     url: '/my/uri',

     // ... whatever else you need
});

无需覆盖fetch(...)并做任何太疯狂的事情。要从服务器获取数据,我认为你已经在做同样的事情:

var collection = new MyCollection();
collection.fetch();

在返回所有数据之前重新渲染,我怀疑您正在使用的视图是在addchange事件上呈现的。如果您想在渲染之前等待所有数据返回,请注册以侦听sync事件,因为当收到所有数据时,集合将触发该事件。

答案 2 :(得分:0)

我首先建议你使用Backbone的api来处理你的XHR请求。它将使其更加一致,并保持Backbone的“fetch”原生。只是一个建议......

提出你的问题。你有两个选择。 使用Backbone的sync api:

示范模型使用“解析”作为“processData”调用。

var MyModel = Backone.Model.extend({

    url: '/my/uri/',

    //http://backbonejs.org/#Model-parse
    parse: function(response) {
        // this is your 'processData' call. Do your logic here. This is done before the consumer gets the data.

        // return the correct object. 
        return response.Data;
    }

})

//用法示例:做您需要做的事情。

var myModel = new MyModel();
myModel.fetch()
    .success(function(data){
        // this is the data AFTER parse has done it's magic. Do other view logic.

    });

以下是在视图中使用它并在模型上订阅“sync”事件的示例。 注意您必须在模型上触发抓取。

var MyView = Backbone.View.extend({

    template: _.template(someHTMLTemplate),

    initialize: function() {
        // setup a sync event that will render once the model fetch is complete. 
        this.model = new MyModel()
            .on('sync', this.render, this);

        // this is just an example and I don't recommend putting fetch in initialize. 
        this.model.fetch();
    },

    render: function() {
        this.$('.content').html(this.template({
            model: this.model.toJSON()
        }));
    }
});

我会尽可能地避免使用自定义触发器,因为它们很难维护,如果每个人在命名约定和使用方面都不一致,很容易在大型团队中失控!

最后,如果视图在呈现之前需要执行一些事件,那么我将使用$ .when方法来跟踪promise对象。