2013-12-16 1 views
15

Есть ли хороший способ сделать результат обещания в шаблоне ручек?Предоставление разрешенного значения обещания в шаблоне ручек 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') 
}); 

И я хотел бы вынести значение позиции в руле шаблон:

{{topicItem.paddedPosition}} 

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

+0

похоже, что вам нужно ждать возвращения 'paddedPosition', что-то вроде' topicItem.get ('paddedPosition'). Then (function() {Handlebars.compile() ;}); 'не уверен в ember, но это общий подход :) – roo2

+0

Не уверен, что ждать paddedPosition так же, как пытаться выяснить, разрешает ли Ember.Handlebars обещание автоматически. – alvincrespo

ответ

29

Вы могли бы иметь свойство лениво ставит перед собой, что-то вроде:

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, вы можете различать их по количеству аргументов - 1 для get, более 1 для set (раньше это было 2, теперь вы получаете 3 поэтому лучший способ обнаружить -> 1). Подробнее об этом in the docs.

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

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

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

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

+0

Это очень интересно и полностью сработало для меня. Я пытаюсь понять - как это работает? :) – alvincrespo

+0

@alvincrespo Я обновил ответ с еще одним объяснением - надеюсь, что это имеет смысл. – rlivsey

+0

Большое спасибо за ваше объяснение. Мы провели некоторое тестирование на этом сегодня и обнаружили, что с использованием этого подхода в рулях возникает проблема с прерывистой ситуацией. По какой-то странной причине, несмотря на то, что обещание разрешает и устанавливает значение, значение null по-прежнему подбирается шаблоном. – alvincrespo

1

Это кажется неожиданным поведением. Ошибка в этой ошибке: https://github.com/emberjs/ember.js/issues/11046

+2

После добавления моего +1 к этой проблеме сегодня было закрыто объяснение, что это не но, а скорее функция, которая еще не существует. У них есть планы решить эту проблему в основном, и было рекомендовано/запрошено содействие RFC. – Joe