2013-12-16 92 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() ;});'不確定燼,但這是一般的方法:) – 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個,設置超過1個(它曾經是2,現在得到3個所以最好的檢測方法是> 1)。更多關於那in the docs

無論從計算屬性(在get還是set中)返回的內容都會被緩存,直到其相關屬性發生更改 - 在本例中爲topic.course.lessons

在上例中,當第一個get進來時,我們啓動計算並返回null。這現在被緩存爲屬性的值,如果其他任何人在promise解決之前調用此屬性,那麼它將返回null

一旦承諾解決,我們就與計算值相同的屬性調用set。我們只是在setter中返回,現在它被緩存爲屬性的值。

直到依賴屬性更改(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