Promise value not put into template after resolved

孤人 提交于 2019-11-30 22:17:48

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 computed property's value is an anti-pattern, the computed property should be just that, a property that computes itself and returns the result. If you set it you will be blasting away the computed property and saying the value of this property is x. This will break the computed property and it won't update anymore after that.

http://emberjs.jsbin.com/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 computed 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.com/OfOhuZub/2/edit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!