最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Promise value not put into template after resolved - Stack Overflow

programmeradmin4浏览0评论

im fairly new to javascript and promises, so I might not get all the basic concepts,but im trying.

I have a function in my model that checks the friendshiptstatus:

 friendShipStatus: function() {
            var self = this;
            return Ember.RSVP.all([this.container.lookup('user:current'), 
                                   this.get('myFriends'), 
                                   this.get('friendsWithMe'), 
                                   this.get('friends')]).then(function(result){
                var user = result[0], myFriends = result[1],
                    friendsWithMe = result[2], friends = result[3] 
                if(friends.contains(user)){
                    return 2;
                } else if(friendsWithMe.contains(user)){
                    return 4;
                } else if(myFriends.contains(user)){
                    return 1;
                } else if (self.get('id') === user.get('id')){
                    return 3;
                } else {
                    return 0;
                }
            });

    }.property('friends')

No I just want to output this value (e.g. 3) in my tmeplate via:

FriendStatus :{{ friendShipStatus}}<br>

But I only get the object output:

FriendStatus :[object Object]

If I log the output via the log helper {{ log friendShipStatus }} I see that the promise is resolved with the value 3. Why is this value then not put into my template?

im fairly new to javascript and promises, so I might not get all the basic concepts,but im trying.

I have a function in my model that checks the friendshiptstatus:

 friendShipStatus: function() {
            var self = this;
            return Ember.RSVP.all([this.container.lookup('user:current'), 
                                   this.get('myFriends'), 
                                   this.get('friendsWithMe'), 
                                   this.get('friends')]).then(function(result){
                var user = result[0], myFriends = result[1],
                    friendsWithMe = result[2], friends = result[3] 
                if(friends.contains(user)){
                    return 2;
                } else if(friendsWithMe.contains(user)){
                    return 4;
                } else if(myFriends.contains(user)){
                    return 1;
                } else if (self.get('id') === user.get('id')){
                    return 3;
                } else {
                    return 0;
                }
            });

    }.property('friends')

No I just want to output this value (e.g. 3) in my tmeplate via:

FriendStatus :{{ friendShipStatus}}<br>

But I only get the object output:

FriendStatus :[object Object]

If I log the output via the log helper {{ log friendShipStatus }} I see that the promise is resolved with the value 3. Why is this value then not put into my template?

Share Improve this question asked Feb 1, 2014 at 10:17 m0cm0c 2,19126 silver badges45 bronze badges 4
  • What if - instead of returning the RSVP all you set a string value (initialized above the RSVP call) and at the bottom of the function you simply return that empty string and let the data bind magic change it during they callback? – Toran Billups Commented Feb 1, 2014 at 13:15
  • Try replacing the return 3 with self.set('friendShipStatus', 3) – RustyToms Commented Feb 1, 2014 at 14:50
  • I did it now with self.set ..... post it as an answer that I can accept it – m0c Commented Feb 1, 2014 at 16:41
  • You definitely don't want to do that... – Kingpin2k Commented Feb 1, 2014 at 17:15
Add a ment  | 

1 Answer 1

Reset to default 8

There is a more advanced approach below, but this approach works as well.

You're going to want to use an observer, then set another property to the result. Computed properties that result in promises should be used as promises (in the case that something else want's to wait until the value is available).

Setting a puted property's value is an anti-pattern, the puted property should be just that, a property that putes itself and returns the result. If you set it you will be blasting away the puted property and saying the value of this property is x. This will break the puted property and it won't update anymore after that.

http://emberjs.jsbin./OfOhuZub/1/edit

goodValue: '',
  
goodObserves: function(){
    var self = this,
        change = this.get('yourInput'),
        promise;
    
    promise = new Ember.RSVP.Promise(function(resolve){
      Em.run.later(function(){
        resolve(change);
      }, 200);
    });
     
    promise.then(function(result){
       self.set('goodValue', result);
    });
    
}.observes('yourInput').on('init'),
 
badComputed: function(){
    var self = this,
        change = this.get('yourInput'),
        promise;
    
    promise = new Ember.RSVP.Promise(function(resolve){
      Em.run.later(function(){
        resolve(change);
      }, 200);
    });
     
    promise.then(function(result){
       // AHHH, I'm overwriting my puted property, Whoops
       self.set('badComputed', result);
    });
}.property('yourInput')

In your case it would be something like this:

friendShipStatus: '',
friendShipStatusObserver: function() {
        var self = this;
        Ember.RSVP.all([this.container.lookup('user:current'), 
                               this.get('myFriends'), 
                               this.get('friendsWithMe'), 
                               this.get('friends')]).then(function(result){
            var user = result[0], myFriends = result[1],
                friendsWithMe = result[2], friends = result[3] 
            if(friends.contains(user)){
                self.set('friendShipStatus', 2);
            } else if(friendsWithMe.contains(user)){
                self.set('friendShipStatus', 4);
            } else if(myFriends.contains(user)){
                self.set('friendShipStatus', 1);
            } else if (self.get('id') === user.get('id')){
                self.set('friendShipStatus', 3);
            } else {
                self.set('friendShipStatus', 0);
            }
        });

}.observes('friends')

More advanced approach

You can also build a promise proxy object which may work easier in your case. Essentially you build up an ObjectProxy (this is the same thing that ObjectController uses for proxying property from the model to the template). But you add a twist, you use the PromiseProxyMixin which will allow you to proxy values from the resolution of the promise. You can't use just the result, {{goodComputed}}, this would just print out the promise proxy. So you'll want to wrap your resolved value in an object of some sort, resolve({value: change}). Once in an object you could use {{goodComputed.value}} in the template and it will proxy down to the promise since value doesn't exist on the ObjectProxy. I've included an example below.

  goodComputed: function(){
    var self = this,
        change = this.get('yourInput'),
        promise,
        result;
    promise = new Ember.RSVP.Promise(function(resolve){
      Em.run.later(function(){
        resolve({value:change});
      }, 200);
    });
     
    result = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin).create({
      promise: promise
    });
    
    return result;
  }.property('yourInput'),

http://emberjs.jsbin./OfOhuZub/2/edit

发布评论

评论列表(0)

  1. 暂无评论