【问题标题】:Template.onRendered() called too earlyTemplate.onRendered() 调用过早
【发布时间】:2015-10-12 20:05:05
【问题描述】:

我遇到了一个奇怪的问题。我正在使用hammer.js 配置长按事件,并在 Template.onRendered() 回调中附加事件观察器。这在我的本地开发机器上完美运行。但是,当我部署到服务器时,似乎在模板完成在浏览器中呈现之前触发了 onRendered()。 jQuery 选择器为空。我不得不求助于设置计时器以确保在配置事件处理程序之前呈现模板。或者,我尝试在 Tracker.afterFlush() 中配置事件处理程序来代替 setTimeout(),但是当它触发时模板仍然没有呈现。

看来我不应该在这里使用 setTimeout() 。我做错了什么或不正常吗?

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);

});

【问题讨论】:

    标签: javascript jquery meteor meteor-blaze


    【解决方案1】:

    前几天有人回答了这个问题,但肯定是撤回了他们的回答。他们建议模板实际上已渲染,但数据订阅尚未完成复制。他们是对的。

    我能够验证在设置我的 java 脚本事件之前我需要等到数据订阅完成。

    【讨论】:

      猜你喜欢
      • 2011-03-22
      • 2012-10-31
      • 2015-12-04
      • 2013-05-28
      • 1970-01-01
      • 1970-01-01
      • 2016-04-14
      • 2013-05-06
      • 2014-03-10
      相关资源
      最近更新 更多