有没有一种好方法可以在把手模板中呈现承诺的结果?
例如,我有以下模型:
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 :(得分: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
。现在将其缓存为属性的值,如果在promise已解决之前还有其他任何内容调用此属性,则它将返回null
。
承诺解决后,我们使用计算值在同一媒体资源上调用set
。我们只是在setter中返回它现在被缓存为属性的值。
在依赖属性更改(topic.course.lessons
)或新值为set
之前,将从属性返回缓存的值。
答案 1 :(得分:1)
这似乎是一种意想不到的行为。 这个问题填补了一个错误:https://github.com/emberjs/ember.js/issues/11046