解决后未将承诺值放入模板 [英] Promise value not put into template after resolved

查看:22
本文介绍了解决后未将承诺值放入模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 javascript 和 Promise 还很陌生,所以我可能没有掌握所有的基本概念,但我正在尝试.

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

我的模型中有一个函数可以检查friendshiptstatus:

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')

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

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

FriendStatus :{{ friendShipStatus}}<br>

但我只得到对象输出:

FriendStatus :[对象对象]

FriendStatus :[object Object]

如果我通过日志帮助程序 {{ logfriendShipStatus }} 记录输出,我看到 Promise 的解析值为 3.为什么这个值没有放入我的模板中?>

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?

推荐答案

下面有更高级的方法,但这种方法也有效.

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

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).

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

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')

更高级的方法

您还可以构建一个 promise 代理对象,这在您的情况下可能更容易使用.本质上,您构建了一个 ObjectProxy(这与 ObjectController 用于将属性从模型代理到模板的东西相同).但是你添加了一个扭曲,你使用 PromiseProxyMixin 这将允许你从承诺的解析中代理值.您不能只使用结果 {{goodComputed}},这只会打印出承诺代理.因此,您需要将解析的值包装在某种对象中,resolve({value: change}).一旦在一个对象中,您可以在模板中使用 {{goodComputed.value}} 并且它将代理到承诺,因为 ObjectProxy 上不存在值.我在下面提供了一个示例.

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

这篇关于解决后未将承诺值放入模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆