【发布时间】:2015-03-15 10:25:27
【问题描述】:
我想根据我收藏的数据创建图表。 此数据由我的路由器设置中的聚合拉取调用,并由 template.rendered 函数中的 Session.data 设置。
Meteor.call 被放置在 waitOn 函数中。 如果模板被渲染,则数据不存在。
我尝试了 onBeforeAction、action、setTimeout... 但我无法将渲染函数设置为等到调用数据出现。
我尝试在我的 RouteController 和 Router.route 的操作、waitOn 和数据函数中设置 onBeforeAction 和 onRun 挂钩中的调用。
我用 setTimeout 包装了我的渲染代码,但它不起作用。
Router.configure({
layoutTemplate: 'global',
loadingTemplate: 'loading',
notFoundTemplate: 'notFound',
});
Router.onBeforeAction("loading");
在我的全局路由设置中设置。
我已经尝试过以下解决方案:
question 23575826
question 26198531
https://github.com/EventedMind/iron-router/issues/554#issuecomment-39002306
最后几天还有更多。
对我的路由器设置或其他解决此问题并及时呈现数据的方法有什么建议吗? 我考虑选择 npm-modules fiber/future,但我不知道如何嵌入和使用它们。
我的设置: 流星是 v1.0.2.1
router.js 自带控制器
StatsController = RouteController.extend({
template: 'statsShow',
waitOn: function () {
return [
Meteor.call('saleGetDataPerYear', 'nYWpgxR3kEY8kwBkA', 'SellerOne', 2014, function(error, result){
if(!error)
Session.set('brockhausUnits', result['units']);
Session.set('brockhausVolumes', result['volumes']);
}),
Meteor.call('saleGetDataPerYear', 'nYWpgxR3kEY8kwBkA', 'SellerTwo', 2014, function(error, result){
if(!error)
Session.set('info3Units', result['units']);
Session.set('info3Volumes', result['volumes']);
}),
Meteor.call('saleGetDataPerYear', 'nYWpgxR3kEY8kwBkA', 'SellerThree', 2014, function(error, result){
if(!error)
Session.set('avaUnits', result['units']);
Session.set('avaVolumes', result['volumes']);
})
];
},
data: function () {
return Books.findOne({_id: this.params._id});
},
action: function () {
if (!this.ready()) {
this.render('Loading');
} else {
this.render();
}
}
});
Router.route('stats/show/', {
name: 'stats.show',
controller: 'TestController'
});
methods.js
Meteor.methods({
saleGetDataPerYear: function(bookId, seller, year) {
var sellerUnits = [];
var sellerVolumes = [];
var resultData = {};
var pipeline = [
{
$match : { bookId: bookId, salesSeller: seller, salesYear: year }
},
{
$group : {
_id : {
sale: { "salesMonth": "$salesMonth" }
},
units: { $sum: "$salesUnits" },
volumes: { $sum: "$salesVolumes" },
month: { $first: "$salesMonth" },
year: { $first: "$salesYear" },
seller: { $first: "$salesSeller" }
}
},
{
$sort : {
month: 1
}
}
];
result = Sales.aggregate(pipeline);
if(result){
sellerUnits.push(seller);
sellerVolumes.push(seller);
result.forEach(function(data){
sellerUnits.push(data.units);
sellerVolumes.push(data.volumes);
});
resultData['units'] = sellerUnits;
resultData['volumes'] = sellerVolumes;
}
if(resultData){
return resultData;
} else {
throw new Meteor.Error("no-data", "No Data collected");
}
}
模板
//-- template rendered functions
Template.statsShow.rendered = function(){
var chartUnitsBrockhaus = Session.get('brockhausUnits');
var chartUnitsInfo3 = Session.get('info3Units');
var chartUnitsAva = Session.get('avaUnits');
var chartUnitsSumme = Session.get('sumUnits');
console.log(chartUnitsBrockhaus);
var chartUnits = c3.generate({
bindto: this.find('.chartUnits'),
data: {
columns: [
chartUnitsBrockhaus,
chartUnitsInfo3,
chartUnitsAva,
chartUnitsSumme
],
type: 'bar',
types: {
Summe: 'spline',
},
},
axis: {
x: {
type: 'category',
categories: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
}
},
bar: {
width: {
ratio: 0.5
}
}
});
};
包
accounts-password 1.0.5
accounts-ui 1.1.4
alanning:roles 1.2.13
aldeed:autoform 4.2.2
aldeed:autoform-select2 1.0.3
aldeed:collection2 2.3.1
aldeed:simple-schema 1.3.0
anti:fake 0.4.1
chrismbeckett:fontawesome4 4.2.2
coffeescript 1.0.5
ctjp:meteor-bootstrap-switch 3.3.1_1
dburles:collection-helpers 1.0.2
francocatena:status 1.0.3
iron:router 1.0.7
lepozepo:accounting 1.0.0
less 1.0.12
matteodem:easy-search 1.4.6
meteor-platform 1.2.1
meteorhacks:aggregate 1.1.0
mrt:jquery-csv 0.7.1
natestrauser:select2 3.5.1
nemo64:bootstrap 3.3.1_1
ongoworks:security 1.0.1
peerlibrary:xml2js 0.4.4_3
peernohell:c3 1.1.2
sacha:spin 2.0.4
service-configuration 1.0.3
underscore 1.0.2
zimme:select2-bootstrap3-css 1.4.1
编辑
正如@DavidWeldon 提到的,我将 waitOn 函数更改为:
waitOn: function () {
return [
// first call
Meteor.callWithReady('saleGetDataPerYear', 'nYWpgxR3kEY8kwBkA', 'Brockhaus', 2014, function(error, result){
if(!error) {
console.log(result); //debug
Session.set('brockhausUnits', result['units']);
Session.set('brockhausVolumes', result['volumes']);
};
}),
// second call
Meteor.callWithReady('saleGetDataPerYear', 'nYWpgxR3kEY8kwBkA', 'Info3', 2014, function(error, result){
if(!error) {
console.log(result); //debug
Session.set('brockhausUnits', result['units']);
Session.set('brockhausVolumes', result['volumes']);
};
}),
// third call
Meteor.callWithReady('saleGetDataPerYear', 'nYWpgxR3kEY8kwBkA', 'AVA', 2014, function(error, result){
if(!error) {
console.log(result); //debug
Session.set('brockhausUnits', result['units']);
Session.set('brockhausVolumes', result['volumes']);
};
}),
// fourth call
Meteor.callWithReady('saleGetSumDataPerYear', 'nYWpgxR3kEY8kwBkA', 2014, function(error, result){
if(!error) {
console.log(result); //debug
Session.set('sumUnits', result['units']);
Session.set('sumVolumes', result['volumes']);
}
})
];
},
并在/lib下添加了test.coffee:
_.defaults Meteor,
callWithReady: (method, options...) ->
dep = new Deps.Dependency
ready = false
lastOption = _.last options
if _.isFunction lastOption
Meteor.apply method, _.initial(options), (err, result) ->
lastOption err, result
ready = true
dep.changed()
else
Meteor.apply method, options, (err, result) ->
ready = true
dep.changed()
ready: ->
dep.depend()
ready
结果是:我的通话循环。
我测试了@apendua 的答案。
function waitUntilDone (action) {
var isReady = new ReactiveVar(false);
action(function () {
isReady.set(true);
});
return {
ready: function () {
return isReady.get();
}
};
}
waitOn: function () {
return [
// first call
waitUntilDone(function(done) {
Meteor.callWithReady('saleGetDataPerYear', 'nYWpgxR3kEY8kwBkA', 'Brockhaus', 2014, function(error, result){
if(!error) {
console.log(result); //debug
Session.set('brockhausUnits', result['units']);
Session.set('brockhausVolumes', result['volumes']);
};
done();
})
}),
// second call
waitUntilDone(function(done) {
Meteor.call('saleGetDataPerYear', 'nYWpgxR3kEY8kwBkA', 'Info3', 2014, function(error, result){
if(!error) {
console.log(result); //debug
Session.set('brockhausUnits', result['units']);
Session.set('brockhausVolumes', result['volumes']);
done();
};
})
}),
// third call
waitUntilDone(function(done) {
Meteor.call('saleGetDataPerYear', 'nYWpgxR3kEY8kwBkA', 'AVA', 2014, function(error, result){
if(!error) {
console.log(result); //debug
Session.set('brockhausUnits', result['units']);
Session.set('brockhausVolumes', result['volumes']);
done();
};
})
}),
// fourth call
waitUntilDone(function(done) {
Meteor.call('saleGetSumDataPerYear', 'nYWpgxR3kEY8kwBkA', 2014, function(error, result){
if(!error) {
console.log(result);
Session.set('sumUnits', result['units']);
Session.set('sumVolumes', result['volumes']);
done();
}
})
})
];
},
或
waitOn: function () {
return [
// first call
waitUntilDone(function(done) {
Meteor.callWithReady('saleGetDataPerYear', 'nYWpgxR3kEY8kwBkA', 'Brockhaus', 2014, function(error, result){
if(!error) {
console.log(result); //debug
Session.set('brockhausUnits', result['units']);
Session.set('brockhausVolumes', result['volumes']);
};
done();
}),
Meteor.call('saleGetDataPerYear', 'nYWpgxR3kEY8kwBkA', 'Info3', 2014, function(error, result){
if(!error) {
console.log(result); //debug
Session.set('brockhausUnits', result['units']);
Session.set('brockhausVolumes', result['volumes']);
done();
};
})
[...]
})
];
},
两个结果都是:我的调用循环。
【问题讨论】:
-
waitOn不能直接与Meteor.call一起使用,您需要一些更详细的代码才能使其正常工作;你在哪里看到过这样的例子? -
你可以看到我的 Meteor.callWithReady here 的实现。它在早期版本的 IR 中对我们有用,但我没有用 1.x 测试它。您可以尝试用
Meteor.callWithReady替换您的Meteor.call,看看它是否有效。 -
@apendua 这不是一个例子。我想到了。我需要聚合函数来总结一些收集数据,但我不知道这将如何与订阅一起使用,所以我选择了调用...
-
顺便说一句,在
if (!error)之后,您可能需要使用大括号来创建新块。缩进不会像python那样创建新块。 -
@David 谢谢,我会测试你的解决方案并报告
标签: meteor iron-router