AJAX promise without Ember Data

前端 未结 3 853
夕颜
夕颜 2020-12-07 15:00

I have decided to not use ember-data as it\'s not production ready and still changing. My app only needs to make a few ajax requests anyway so it shouldn\'t make too big of

相关标签:
3条回答
  • 2020-12-07 15:36

    Actually the answer is quite easy: You do not need to use a promise. Instead just return an empty object. Your code could look like this:

    App.User.reopenClass({
        getCurrentUser: function() {
            var user = App.User.create({}); //create an empty object
            $.ajax({
                url: "/api/get_current_user",
                type: "POST",
                data: JSON.stringify({})
            }).then(function(response) {
                user.setProperties(response); //fill the object with your JSON response
            });
            return user;
        }
    });
    

    What is happening here?

    1. You create an empty object.
    2. You make an asynchronous call to your API...
    3. ... and in your success callback you fill your empty object.
    4. You return your user object.

    Note: What is really happening? The flow mentioned above is not the sequence in which those actions are happening. In reality the points 1,2 and 4 are performed first. Then some time later, when the response returns from your server, 3 is executed. So the real flow of actions is: 1 -> 2 -> 4 -> 3.

    So the general rule is to always return an object that enables Ember to do its logic. No values will be displayed first in your case and once your object is filled Ember will start do its magic and auto update your templates. No hard work needs to be done on your side!


    Going beyond the initial question: How would one do this with an array? Following this general rule, you would return an empty array. Here a little example, which assumes, that you might like to get all users from your backend:

    App.User.reopenClass({
        getAllUsers: function() {
            var users = []; //create an empty array
            $.ajax({
                url: "/api/get_users",
            }).then(function(response) {
                response.forEach(function(user){
                    var model = App.User.create(user); 
                    users.addObject(model); //fill your array step by step
                });
            });
            return users;
        }
    });
    
    0 讨论(0)
  • 2020-12-07 15:42

    I'd use Ember.Deferred instead of returning an empty array as mentioned before.

    App.User.reopenClass({
      getAllUsers: function() {
        var dfd = Ember.Deferred.create();
        var users = [];
    
        $.ajax({
            url: "/api/get_users",
        }).then(function(response) {
            response.forEach(function(user){
                var model = App.User.create(user); 
                users.addObject(model);
            });
            dfd.resolve(users);
        });
        return dfd;
      }
    });
    

    In your model hook all you have to do is this

    model: function(){
      return App.User.getAllUsers();
    }
    

    Ember is smart enought and knows how to handle the promise you return, once it's resolved the model will be correctly set, you can also return a jQuery promise but it will give you some weird behavior.

    0 讨论(0)
  • 2020-12-07 15:55

    You can as well set the current user as the model for your ApplicationRoute like so:

    App.ApplicationRoute = Ember.Route.extend({
        model: function() {
            return App.User.getCurrentUser();
        }
    });
    

    Since getCurrentUser() returns a promise, the transition will suspend until the promise either fulfills or rejects.

    This is handy because by the time transition is finished your model is initialized and you will see it rendered in the template.

    You can read up more about async routing in Ember guides.

    0 讨论(0)
提交回复
热议问题