Предоставление разрешенной суммы обещаний в шаблоне ручек Ember

Есть ли хороший способ сделать результат обещания в шаблоне рулей?

Например, у меня есть следующая модель:

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

И я хотел бы отобразить значение позиции в шаблоне handlebars следующим образом:

{{topicItem.paddedPosition}}

Есть ли хороший способ сделать это?

Ответы

Ответ 1

У вас может быть свойство лениво настроено, например:

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 ready
      return value;
    }
  }.property('topic.course.lessons')
});

При первом обращении к нему он начнет вычисление, так же как и в любое время, когда уроки меняются, тогда он будет установлен как результат вычисления после его выполнения.

Это работает, потому что вычисленное свойство вызывается как для get, так и для set, вы можете различать между ними по количеству аргументов - 1 для get, более 1 для set (раньше это было 2, теперь вы получаете 3 так лучший способ обнаружения → 1). Подробнее об этом в документах.

Все, что возвращается из вычисленного свойства (либо в get или set), кэшируется до тех пор, пока его зависимые свойства не изменятся - в этом случае topic.course.lessons.

В приведенном выше примере, когда приходит первый get, мы начинаем вычисление и возвращаем null. Теперь это кэшируется как значение свойства, если что-либо еще вызывает это свойство до того, как обещание будет разрешено, оно вернет null.

Как только обещание разрешится, мы вызываем set в том же свойстве с вычисленным значением. Это мы просто возвращаем в сеттер и теперь кэшируем как значение свойства.

До изменения зависимых свойств (topic.course.lessons) или нового значения set, тогда кэшированное значение возвращается из свойства.