简体   繁体   English

Template.onRendered()调用为时过早

[英]Template.onRendered() called too early

I have hit a strange problem. 我遇到了一个奇怪的问题。 I am using hammer.js to configure long-press events, and attaching the event watcher within the Template.onRendered() callback. 我正在使用Hammer.js来配置长按事件,并将事件观察程序附加到Template.onRendered()回调中。 This works perfectly on my local development machine. 这在我的本地开发机器上完美运行。 However, when I deploy to a server, it seems that onRendered() is being fired before the template is finished rendering in the browser. 但是,当我部署到服务器时,似乎在模板在浏览器中完成渲染之前已触发onRendered()。 The jQuery selector is empty. jQuery选择器为空。 I've had to resort to setting a timer to make sure the template is rendered before configuring the event handler. 在配置事件处理程序之前,我不得不求助于设置计时器以确保模板已呈现。 Alternatively, I've tried configuring the event handler within a Tracker.afterFlush() in place of setTimeout(), but the template is still not rendered when this fires. 另外,我尝试在Tracker.afterFlush()中代替setTimeout()配置事件处理程序,但是在触发时仍无法呈现模板。

It seems that I shouldn't have to use setTimeout() here. 看来我不必在这里使用setTimeout()。 Am I doing something wrong or out of order? 我是在做错事还是乱序?

Template.CATEGORIES.onRendered(function () {

Meteor.setTimeout(function () {
    console.log('setting up hammer object', this.$('.collapsible'));
    var h = this.$('.collapsible').hammer({domEvents:true});
    h.on('tap press swipe pan', '.collapsible-header', function (ev) {
        // get the ID of the shopping list item object
        var target = ev.target;
        var $target = $(target);
        var type = ev.type;
        var $header = $target;
        if (Collapse.isChildrenOfPanelHeader($target)) {
            $header = Collapse.getPanelHeader($target);
        }

        console.log('Firing ', type, ' on ', $header);
        Kadira.trackError('debug', 'Firing ' + type + ' on ' + $header);

        // handler for checkbox
        if (type === 'tap' && $target.is('label')) {

            var data = Blaze.getData(target);
            var TS = data.checkedTS;
            ev.preventDefault();
            data.checked = !data.checked;

            console.log('Checkbox handler', data);

            if (data.checked && !TS) {
                TS = new Date()
            } else if (!data.checked) {
                TS = null
            }

            // Set the checked property to the opposite of its current value
            ShoppingList.update(data._id, {
                $set: {checked: data.checked, checkedTS: TS}
            });

        } else if (type === 'tap' && $target.has('.badge')) {
            // if the user taps anywhere else on an item that has a child with .badge class
            // this item has deals.  Toggle the expand.

            console.log('badge handler');

            $header.toggleClass('active');
            Collapse.toggleOpen($header);

        } else if (type === 'press' || type === 'swipe' || type === 'pan') {
            // remove any selected deals
            var itemID, item;
            var $label = $header.find('label');

            console.log('long press handler');

            if ($label) {
                itemID = $label.attr('for');
                item = ShoppingList.findOne(itemID);
                if (item && item.deal) {
                    Deals.update(item.deal._id, {$set: {'showOnItem': false}});
                    ShoppingList.update(itemID, {$set: {'deal': null}});
                }
            }
        }

    })

}, 2000);

});

Someone answered this the other day but must have withdrawn their answer. 前几天有人回答了这个问题,但肯定已经撤回了答案。 They suggested that the template was actually rendered, but that the data subscription had not finished replicating yet. 他们建议实际渲染模板,但数据订阅尚未完成复制。 They were right. 他们是对的。

I was able to validate that I need to wait until the data subscription finishes prior to setting up my java script events. 我能够验证是否需要等待数据订阅完成之后再设置Java脚本事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM