我使用jQuery getJSON在我的ember.js应用程序(ember 1.7.0)中获取数据。 加载数据时渲染模板有一个小问题。
这是我的第一个方法:
Parivar.Router.reopen({
rootURL: '/account/'
});
Parivar.Router.map(function() {
this.route('orders', { path: '/orders' });
this.route('order', {path: '/orders/:number'});
});
Parivar.IndexRoute = Ember.Route.extend({
beforeModel: function(){
this.transitionTo('orders');
}
});
Parivar.Order = Ember.Object.extend({});
Parivar.Order.reopenClass({
findMine: function(params) {
return $.getJSON('/api/orders/mine?page=' + params.page);
},
order: function(params) {
return $.getJSON('/api/orders/' + params.number);
}
});
Parivar.OrdersRoute = Ember.Route.extend({
queryParams: {
page: {
refreshModel: true
}
},
model: function(params) { return Parivar.Order.findMine(params); }
});
Parivar.OrderRoute = Ember.Route.extend({
model: function(params) { return Parivar.Order.order(params); }
});
Parivar.ApplicationController = Ember.Controller.extend({
renderHeader: function() {
return this.get('currentRouteName') === 'orders';
}.property('currentRouteName')
});
Parivar.OrdersController = Ember.ObjectController.extend({
queryParams: ['page'],
page: 1,
needPaginate: function() {
return this.get('model.pages') != 1;
}.property('model.pages')
});
Parivar = Ember.Application.create({
rootElement: '#ember_orders',
LOG_TRANSITION: true,
LOG_ACTIVE_GENERATION: true,
LOG_VIEW_LOOKUPS: true,
ready: function() {
console.log("Ember.TEMPLATES: ", Ember.TEMPLATES);
}
});
我需要模板(应用程序,订单,订单,标题和加载) 在application.hbs中:
{{#if renderHeader}}
{{partial 'header'}}
{{/if}}
{{outlet}}
一切正常(我有一个很好的加载模板!),除了渲染标题模板。它仅在加载所有数据并且加载模板消失后才显示。但我想在加载应用程序后立即显示标题。
我的第二种方法是使用beforeModel钩子。我试图将标题模板渲染到名为outlet的那里。但我得到并且错误地说没有名称标题的插座。当beforeModel中的代码执行时,可能没有出口?
在我的第三次尝试中,我将Order类中的findMine更改为:
findMine: function(params) {
var orders = Parivar.Order.create();
Ember.$.getJSON('/api/orders/mine?page=' + params.page).then(function(result) {
orders.setProperties(result);
});
return orders;
}
所以,我有空订单对象立即返回给应用程序,然后填充数据。 一切正常,除了我没有渲染我的加载模板,并显示用户"你没有订单"直到数据在订单对象中填充。所有这些都是由返回空订单对象引起的。
这是一个问题:如何在加载数据之前呈现标题模板,同时仍然有令人敬畏的加载'模板功能?
任何帮助将不胜感激。
答案 0 :(得分:1)
首先,您需要了解加载子状态的工作原理。有关详细信息,请查看http://emberjs.com/guides/routing/loading-and-error-substates/
一般来说,对于beforeModel
,model
,afterModel
未立即解决的路线,Ember将尝试查找是否存在loading
路线水平。如果存在loading
路由,则Ember将进入该路由,直到解析出所有模型挂钩。在您的情况下,如果您想在加载数据之前显示标题,则需要将标题放在orders
模板之外。
有几种方法可以解决您的问题。
是否需要为所有页面显示标题?如果是这样,您可以将标题放在orders
路线的上层路线模板中,即application
模板。
在application.hbs
{{partial 'header'}}
{{outlet}}
然后在orders
路由model
挂钩中您可以返回一个承诺,然后会触发loading
路由。
如果您的标题仅在orders
路由中呈现,则可以在子路径中加载数据。 orders.index
路线是一个好地方。
Parivar.Router.map(function() {
// This will create index, loading, error sub-states under orders
// Note the blank function is needed even in Ember 1.7.0
this.resource('orders', function() {});
});
Parivar.OrdersIndexRoute = Em.Route.extend({
model: function(params) {
return Parivar.Order.findMine(params);
}
});
将标题放在orders.hbs
{{#if renderHeader}}
{{partial 'header'}}
{{/if}}
{{outlet}} {{! will render "orders.index" here }}
您还需要orders/loading.hbs
来触发加载子状态。或者您可以覆盖路由的loading
操作以实现您自己的加载逻辑。
可在此处找到jsbin示例:http://emberjs.jsbin.com/sawez/3/edit
这对你的案子来说不是一个好方法所以我不会说很详细的事情。我们的想法是将setupController钩子和mixin Em.PromiseProxyMixin
中的数据加载到您的控制器中,然后您可以在yoru控制器中使用isFulfilled
,isRejected
和isPending
属性来呈现不同的内容。有关如何使用Em.PromiseProxyMixin
,您可以看到this API documentation