简体   繁体   中英

How do I make sure a function will be called before another in a deeply modularized Backbone, Require.js and D3 app?

Here is my headache. I'm developing a modularized javascript app and everything seems pretty neat except for one detail: I just can figure out how to load my initialize function only after my models have been fetched from the server with this Backbone.collection.fetch() method.

Please have a look into this file and possibly the whole project if you will, I appreciate a lot your collaboration.

fetch has a success callback, as Reed Spool pointed out. Here's how you could use it:

var View = Backbone.View.extend({

    initialize: function () {
      // Preserve *this* in closures
      var that = this;

      this.collection.fetch({
        success: function(data){
          console.log(data);            
          that.render();
      },
        error: function(){
          console.log('error');
        }
      });

    },

    render: function() {
      //render whatever you need from your fetched collection
    }      

});

If I'm hearin you right, I think you need to use a "Success" callback function in fetch. See here #2 http://chilipepperdesign.com/2013/01/15/backbone-js-bind-callback-to-successful-model-fetch/

If it's decoupling function timing in modularized code you're worried about, as your question's header suggests, I suggest using Backbone's Events. See the Event Aggregator, or Pub-Sub design patterns.

The conventional way to get around this using Backbone, is to use events. I've based this off the various blog posts of MarionetteJS founder Derek Bailey, so I'll add references when I find the relevant ones later...

Your view would do this:

var view = Backbone.View.extend({
    ...
    _actuallyInitialize: function () {
        ...
    }
    initialize: function (attr, options) {
        ...
        this.listenTo(this.model, 'data:fetched', this._actuallyInitialize);
        ...
    }
});

And the code that is fetching your model, would do this:

var jqXHR = model.fetch();
jqXHR.done((function (bindModel) {
    return function (response, textStatus, jqXHR) {
        ...
        bindModel.trigger('data:fetched');
    };
}(model)));

This way, you maintain the high-level modular approach, decouple the code (any number of views can update themselves on fetch now), and maintain readability. Your Model does stuff to itself, and your View does stuff to itself. Pretty neat, in my opinion, and one of the patterns I love using in Backbone. Thanks for the Q.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM