如何仅使 Ember 路由模型的一部分成为承诺?
How to make only part of Ember route model a promise?
我有一个简单的 template.hbs
像这样:
// template.hbs
<p>{{model.x}}</p>
<p>{{model.y}}</p>
以下 route.js 按预期工作:
// route.js
import Route from '@ember/routing/route';
export default Route.extend({
model() {
return {
x: 'foo',
y: 'bar'
};
}
});
// output, immediately:
// foo
// bar
以下也有效,现在对整个模型使用承诺:
// route.js
import Route from '@ember/routing/route';
import RSVP from 'rsvp';
export default Route.extend({
model() {
return new RSVP.Promise((resolve) => {
setTimeout(() => {
resolve({
x: 'foo',
y: 'bar'
});
}, 1000);
});
}
});
// output, after 1s:
// foo
// bar
以下,我只想model.x
一个承诺 - 不起作用。
// route.js
import Route from '@ember/routing/route';
import RSVP from 'rsvp';
export default Route.extend({
model() {
return {
x: new RSVP.Promise((resolve) => {
setTimeout(() => {
resolve('foo');
}, 1000);
}),
y: 'bar'
};
}
});
// output, IMMEDIATELY:
// [object Object]
// bar
它立即渲染输出,但在它进入 setTimeout
的回调后它不会更改 model.x
的渲染值。
我知道 RSVP.hash()
,但如果任何承诺被拒绝,那将被拒绝。是否可以对路由模型的不同部分有独立的承诺,或者只有全有或全无?
奇怪的是,如果有问题的承诺是由 ember-data 返回的,例如x: this.get('store').findRecord('user')
,它正常工作(例如将 template.hbs
更改为 <p>{{model.x.name}}</p>
)。
在最后一个案例中,
model.x
是 Promise 对象,如果你在 hbs 中做 {{log model.x}}
,你可以在控制台中看到它。您可以尝试使用 {{model.x._result}}
访问该值。但这不是正确的做法。
对于你的情况,你可以尝试实现路由的 setupController 钩子,
setupController(controller,model)
{
this._super(...arguments);
let xPromise = new RSVP.Promise((resolve) => {
setTimeout(() => {
resolve('foo');
}, 1000);
});
xPromise.then((result) =>{
this.set('model.x',result);
});
}
您可以使用来自 ember-data:
的 PromiseObject or PromiseArray
export default Ember.Route.extend({
model() {
return {
x: DS.PromiseObject.create({
promise: new RSVP.Promise((resolve) => {
setTimeout(() => {
resolve({name: 'foo'});
}, 5000);
})
}),
y: 'bar'
};
}
});
为此,您的承诺结果必须是一个对象(即 {name: 'foo'}
而不仅仅是 foo
)。然后,您可以在模板中使用 x.name
,它将 return 未定义,直到承诺 returns.
我有一个简单的 template.hbs
像这样:
// template.hbs
<p>{{model.x}}</p>
<p>{{model.y}}</p>
以下 route.js 按预期工作:
// route.js
import Route from '@ember/routing/route';
export default Route.extend({
model() {
return {
x: 'foo',
y: 'bar'
};
}
});
// output, immediately:
// foo
// bar
以下也有效,现在对整个模型使用承诺:
// route.js
import Route from '@ember/routing/route';
import RSVP from 'rsvp';
export default Route.extend({
model() {
return new RSVP.Promise((resolve) => {
setTimeout(() => {
resolve({
x: 'foo',
y: 'bar'
});
}, 1000);
});
}
});
// output, after 1s:
// foo
// bar
以下,我只想model.x
一个承诺 - 不起作用。
// route.js
import Route from '@ember/routing/route';
import RSVP from 'rsvp';
export default Route.extend({
model() {
return {
x: new RSVP.Promise((resolve) => {
setTimeout(() => {
resolve('foo');
}, 1000);
}),
y: 'bar'
};
}
});
// output, IMMEDIATELY:
// [object Object]
// bar
它立即渲染输出,但在它进入 setTimeout
的回调后它不会更改 model.x
的渲染值。
我知道 RSVP.hash()
,但如果任何承诺被拒绝,那将被拒绝。是否可以对路由模型的不同部分有独立的承诺,或者只有全有或全无?
奇怪的是,如果有问题的承诺是由 ember-data 返回的,例如x: this.get('store').findRecord('user')
,它正常工作(例如将 template.hbs
更改为 <p>{{model.x.name}}</p>
)。
在最后一个案例中,
model.x
是 Promise 对象,如果你在 hbs 中做 {{log model.x}}
,你可以在控制台中看到它。您可以尝试使用 {{model.x._result}}
访问该值。但这不是正确的做法。
对于你的情况,你可以尝试实现路由的 setupController 钩子,
setupController(controller,model)
{
this._super(...arguments);
let xPromise = new RSVP.Promise((resolve) => {
setTimeout(() => {
resolve('foo');
}, 1000);
});
xPromise.then((result) =>{
this.set('model.x',result);
});
}
您可以使用来自 ember-data:
的 PromiseObject or PromiseArrayexport default Ember.Route.extend({
model() {
return {
x: DS.PromiseObject.create({
promise: new RSVP.Promise((resolve) => {
setTimeout(() => {
resolve({name: 'foo'});
}, 5000);
})
}),
y: 'bar'
};
}
});
为此,您的承诺结果必须是一个对象(即 {name: 'foo'}
而不仅仅是 foo
)。然后,您可以在模板中使用 x.name
,它将 return 未定义,直到承诺 returns.