承诺在解决后未将值放入模板中

m0c*_*m0c 5 javascript handlebars.js ember.js

我对javascript和promises相当新,所以我可能没有得到所有的基本概念,但我正在尝试.

我的模型中有一个函数可以检查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')
Run Code Online (Sandbox Code Playgroud)

不,我只想通过以下方式在我的tmeplate中输出此值(例如3):

FriendStatus :{{ friendShipStatus}}<br>
Run Code Online (Sandbox Code Playgroud)

但我只得到对象输出:

FriendStatus:[object Object]

如果我通过日志助手记录输出,{{ log friendShipStatus }}我会看到使用值3解析了promise.为什么这个值不会被放入我的模板中?

Kin*_*n2k 8

下面有一个更先进的方法,但这种方法也适用.

您将要使用观察者,然后将另一个属性设置为结果.导致promises的计算属性应该用作promises(在其他东西想要等到值可用的情况下).

设置计算属性的值是反模式,计算属性应该只是一个计算自身并返回结果的属性.如果你设置它,你将爆破计算属性并说这个属性的值是x.这将破坏计算属性,之后不再更新.

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')
Run Code Online (Sandbox Code Playgroud)

在你的情况下,它将是这样的:

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')
Run Code Online (Sandbox Code Playgroud)

更先进的方法

您还可以构建一个promise代理对象,在您的情况下可以更轻松地工作.基本上你构建了一个ObjectProxy(这与ObjectController用于从模型到模板的代理属性相同).但是你添加一个扭曲,你使用PromiseProxyMixin它将允许你从承诺的解决方案代理值.你不能只使用结果{{goodComputed}},这只会打印出promise代理.因此,您需要将已解析的值包装在某种对象中,resolve({value: change}).一旦进入了一个可以{{goodComputed.value}}在模板中使用的对象,它将代理到承诺,因为该值不存在ObjectProxy.我在下面列举了一个例子.

  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'),
Run Code Online (Sandbox Code Playgroud)

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