渲染Blaze模板之前等待数据的流星

时间:2016-01-24 17:43:54

标签: meteor meteor-blaze

我在仪表板上有多个图表,显示计数,分组等。后端数据有超过百万行。我决定不使用订阅。我不需要对图表进行反应性更新。

我的服务器方法正在使用rawCollection,运行聚合来获取结果,我通过我在客户端回调中设置的会话变量将数据分配给我的图表对象。

服务器方法:

function purchasedItemDollarsByCategory () {
    Future = Npm.require('fibers/future');
    var iCat = new Future();
    Purchasing.rawCollection().aggregate([
            {
                $project: {
                    "GLCodeName": 1,
                    "Amount" : 1
                }
            },
            {
                $group : {
                    _id: "$GLCodeName",
                    amount: { $sum : "$Amount" }
                }
            },
            {
                $sort :
                    {_id : 1}
            }
        ],
        function(err,docs) {
            if (err) {
                iCat.throw(err);
            } else {
                iCat.return(docs);
            }
        }
    );
    return iCat.wait();
}

在模板中,我正在调用

function getPurchasedItemDollarsByCategory () {
    Meteor.call('purchasedItemDollarsByCategory', function (err, results) {
        if (err) {
            toastr.error('Something went wrong. Could not retrieve purchased Item  count');
            return false;
        } else {
            Session.set( 'purchasedItemDollarsByCategory', results);
        }
    })
}

现在,我正在使用另一个函数来绘制图表的数据:

function getPurchasedItemCountByCategoryChartData () {
    var allItemsPurchasedByCategory = Session.get('purchasedItemCountByCategory');
    var allGlCodes = [];
    var allItemPurchasedCountDataPoints = [];
    var contractedPurchasedCountDataPoints = [];
    _.forEach(allItemsPurchasedByCategory, function(d) {
        allGlCodes.push(d._id);
        allItemPurchasedCountDataPoints.push(d.items);
    });
    Session.set('allGlCodes', allGlCodes);
    Session.set('allItemPurchasedCountDataPoints', allItemPurchasedCountDataPoints);
}

现在我正在分配' allGlCodes'和' allItemPurchasedCountDataPoints'到Template onRendered事件中的highcharts配置对象。

服务器方法工作正常。客户端也在获取数据。但是,在数据恢复之前,渲染就会发生。因此图表呈现空白。但如果我点击应用程序并返回此页面,我会看到数据。我不确定我是否完全理解发生了什么,但我猜测数据最终会回来并填充会话变量,因为会话是粘滞的,我会在延迟后看到数据。

我想在数据恢复之前不渲染。所以我在Template onCreated中创建了一个ReactiveVar。

this.isLoadingA = new ReactiveVar( false );
this.isLoadingB = new ReactiveVar( false );
this.isLoading = new ReactiveVar ( this.isLoadingA && this.isLoadingB );

现在的问题是我应该将这些设置为假。我正在进行多个服务器调用。我可以为每个调用创建一个isLoading并创建一个allDataReady变量。但是,如果我尝试在我的成功回调中设置服务器方法:

Template.instance().isLoadingA.set( true );

我收到以下错误:

TypeError: Cannot read property 'isLoadingA' of null

我希望我能清楚地解释问题和我的尝试。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我相信自己在Meteor方法的回调中不能使用Template.instance()。你可以这样做:

exampleHelper() {
    var template = Template.instance();
    Meteor.call( 'example', function(error, results) {
        console.log(Template.instance()); // Undefined
        console.log(template);  // What you want in order to set your reactive variables.
    });
}

这将允许您使用反应变量并在回调中适当地设置状态。