简体   繁体   中英

Ember data and Ember StateManager

I have an application that uses ember-data to persit datas and StateManager to drive its global state. Since, loading data is asynchronous, I'm wondering how to catch the event that said that all the data are loaded. Precisely, I have a state named "loading" where I load data with :

App.store.find(App.Model, ....)

When a model is loaded, I do some post processing. This is done in a substate of "loading" named "postprocessing". I transit to "postprocessing" when every modele got a "didLoad" event :

App.Model = DS.Model.extend {
   didLoad: ->
     stateManager.send('postProcess',this)
}

When every data are loaded and post processed, the application should transit to another state "editing" that is at the same level as "loading" :

      loading -> postprocessing
root /
     \
      editing

What's event should I catch to make the transition happen ? Does the ember-data Store has a callback for this ?

When using ember-data, the find method returns an array proxy. You can observe the isLoaded field on that object.

var data = App.store.find(App.Model, {});
data.addObserver('isLoaded', function() {
    if (data.get('isLoaded')) {
        ....
    }
});

But remember to cleanup your observer via removeObserver.

I added this utility to the built in ember-data record array.

DS.RecordArray.reopen({
    onLoad: function(callback) {
        if (this.get('isLoaded')) {
            callback(this);
        } else {
            var that = this;
            var isLoadedFn = function() {
                if (that.get('isLoaded')) {
                    that.removeObserver('isLoaded', isLoadedFn);
                    callback(that);
                }
            }

            this.addObserver('isLoaded', isLoadedFn);
        }

        return this;
    }
}

So now you can just do

App.store.find(App.Model, {}).onLoad(function(data) {
    ....
});

You can also do something like

init: function() {
    this.set('data', App.store.find(App.model, {}));
},

onData: function() {
    if (this.get('data.isLoaded')) {
        ...
    }
}.observes('data.isLoaded')

Try observing "content@each.isLoaded" and calling stateManager.sent("editing"), in the arrayController for the models. Something like:

App.ModelArrayController.reopen({
    didLoadAllContent: function () {
        if (content.everyProperty('isLoaded')) {
            stateManager.transitionTo('editing');
        }
    }.observes("content.@each.isLoaded")
)}

Might be an easier way, of course. Or perhaps a more correct one...

Typically, the model's state would be handled by a Route.

The model hook executes store.find. http://emberjs.com/api/classes/Ember.Route.html#method_model

The afterModel hook will be called after the route's model has resolved (loaded). http://emberjs.com/api/classes/Ember.Route.html#method_afterModel

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