渲染Ember手把模板中解析的promise值

Rendering resolved promise value in Ember handlebars template

本文关键字:promise Ember 渲染      更新时间:2023-09-26

有没有一种好的方法可以在handlebars模板中呈现promise的结果?

例如,我有以下模型:

App.TopicItem = DS.Model.extend({
  topic: DS.belongsTo('topic'),
  paddedPosition: function() {
    return this.get('topic.course.lessons').
      then(function(lessons) {
        return lessons.indexOf(topicItem);
      }).
      then(function(index){
        var position  = index;
        if (position < 0) { 
          return;
        }
        position = position + 1;
        return (position < 10 ? $.rjust(position, 2, '0') : position.toString());
      });
  }.property('topic.course.lessons')
});

我想在车把模板中呈现位置的值,如下所示:

{{topicItem.paddedPosition}}

有什么好方法可以做到这一点吗?

您可以让属性自己惰性地设置,比如:

App.TopicItem = DS.Model.extend({
  topic: DS.belongsTo('topic'),
  paddedPosition: function(key, value) {
    if (arguments.length > 1) {
      // > 1 args = this is a `set`
      return value;
    } else {
      // otherwise this is a `get`
      var _this = this;
      value = null;
      this.get('topic.course.lessons').
        then(function(lessons) {
          // do stuff based on result
          var padded = ...;
          // when the promise is resolved, set this property with the value
          _this.set("paddedPosition", padded);
          // if the promise resolves immediately, set `value` so we return
          // the calculated value and not null
          value = padded;
        });
      // returns null if the promise doesn't resolve immediately, or 
      // the calculated value if it's ready
      return value;
    }
  }.property('topic.course.lessons')
});

当它第一次被访问时,它将启动计算,同样,每当课程发生变化时,一旦完成,它就会将自己设置为计算结果。

这是因为计算属性在get和set上都被调用,你可以通过参数的数量来区分两者——get为1,set为1以上(以前是2,现在是3,所以最好的检测方法是>1)。文档中有更多关于这方面的内容。

从计算属性(在get或set中)返回的任何内容都将被缓存,直到其依赖属性发生更改(在本例中为topic.course.lessons)。

在上面的例子中,当第一个get出现时,我们开始计算并返回null。现在,它被缓存为属性的值,如果在promise解析之前有任何其他调用该属性,那么它将返回null

一旦promise解析,我们就用计算出的值对同一属性调用set。我们只是在setter中返回它,现在它被缓存为属性的值。

在从属属性更改(topic.course.lessons)或新值为set之前,将从该属性返回缓存值。

这似乎是一种意外的行为。有一个错误填补了这个问题:https://github.com/emberjs/ember.js/issues/11046