【问题标题】:How to trigger jQuery in a reactive Environment?如何在反应式环境中触发 jQuery?
【发布时间】:2012-05-22 03:32:42
【问题描述】:

jQuery 和 Meteor

Meteor 是响应式的,诞生于只有一个初始页面加载的 Web 应用世界,jQuery 诞生于服务器生成页面的世界。

那么,问题是……何时在 Meteor 模板上调用 jQuery 插件?

1) 在页面加载时 -> 不工作。数据还没有。

Template.contextualFeed.feedItems = ->
    Feed.find()
    $("abbr.timeago").timeago() # Calling the feed right away is useless as Feed.find() is initially empty and will populate a bit later when subscription is delivering the initial data.

<template name="contextualFeed">
    <ul class="feed {{isActive "feed"}}">
    {{#each feedItems}}
    <li class="popup-holder">
        {{> contextualFeedItem}}
    </li>
    {{/each}}
    </ul>
</template>

2) 在每个项目上-> 有效,但似乎非常浪费。

Template.contextualFeed.feedItems = ->
    Feed.find()

Template.contextualFeed.jQueryMe = ->
    $("abbr.timeago").timeago() # Works, but seems incredibly wasteful


<template name="contextualFeed">
    <ul class="feed {{isActive "feed"}}">
    {{#each feedItems}}
    <li class="popup-holder">
        {{> contextualFeedItem}}
        {{jQueryMe}}
    </li>
    {{/each}}
    </ul>
</template>

3) 加载所有项目后一次 -> 有效,但仍然没有应有的优雅......

Template.contextualFeed.feedItems = ->
    Feed.find()

Template.contextualFeed.jQueryMe = ->
    Meteor.defer ->
        #(cut) some ugly code to make sure it only executes once.
        $("abbr.timeago").timeago() # Works, but seems incredibly wasteful


<template name="contextualFeed">
    <ul class="feed {{isActive "feed"}}">
    {{#each feedItems}}
    <li class="popup-holder">
        {{> contextualFeedItem}}
        {{jQueryMe}}
    </li>
    {{/each}}
    </ul>
</template>

4) 当数据不是作为添加单独加载到每个项目上时,是否会触发某些事件?

那么,你有在 Meteor 模板中调用 jQuery 的更简洁的方法吗?

PS:代码示例在 Coffeescript 中...尽管如此,请保持良好状态 ;)

【问题讨论】:

    标签: jquery coffeescript publish-subscribe meteor


    【解决方案1】:

    wordplay/client/wordplay.js开头,Meteor的例子之一:

    Words.find({player_id: Session.get('player_id'), state: 'bad'})
        .observe({
            added: function (word) {
                setTimeout(function () {
                    $('#word_' + word._id).fadeOut(1000, function () {
                        Words.remove(word._id);
                    });
                }, 5000);
            }
        }
    );
    

    你不需要你的模板来触发你的 JS 逻辑。只需使用.observe

    【讨论】:

    • 谢谢你:)。我一直在使用观察,但为加载的每个项目添加了一次触发器,这对我的(全局)jQuery 代码来说似乎有点过分......
    • 是的,它并不是要插入触发器。
    【解决方案2】:

    我认为这里有两种潜在的思路。您在 #4 中提出的想法,“dataLoaded”事件可能需要一些对话。但是,我想到的第一个论点是,正如您所说的,Meteor 是新一代的流体 Web 应用程序框架。在那个世界中,加载了初始数据集究竟意味着什么?

    第二个可能是您的问题有更好的解决方案。在某些情况下,jQuery 和 Meteor 的合并可能会让人感觉很笨拙,但是在粗略阅读了您的示例代码之后,我觉得在这个示例中可能有更好的方法。看起来您有一个 Feed 集合,并希望显示每个 Feed 项的实时时间戳,例如“2 小时前”。那是对的吗?

    如果是这样:我不认为如果您不打算将活动时间戳存储在 Mongo 中,那么示例 #2 会非常浪费。诚然,我不确定 Meteor 中的最佳方式,但您应该能够在应用程序中缓存时间戳值。您可能要考虑的另一件事是将值与 Unix 时间戳分开存储在 Mongo 中 - 例如,几个小时。您可以在服务器上运行一个进程来更新提要项目的已用时间。这是可持续的,假设提要项目最终会过时,它们的数量并不多,而且您不需要对时间戳非常精确。

    我没有任何数据,也不认为这些方法 a) 正确且 b) 比明显的解决方案更快,但它值得深思。


    ETA:Meteor.subscribe 可能有用http://docs.meteor.com/#meteor_subscribe。请参阅 todo 示例中的用法:https://github.com/meteor/meteor/blob/master/examples/todos/client/todos.js

    【讨论】:

    • 嘿 theresaanna,是的,我正在尝试使用 jQuery 插件将日期/时间戳转换为“2 小时”前。在示例 2 中,jQuery 初始化代码将基本上在循环中调用,每个提要项一次,这似乎有点矫枉过正......
    • 感谢您的回答...这让我开始思考并添加回调订阅确实是我应该尝试的事情...在过去我一直使用的框架中只是有一个将事件绑定到集合的方式,以便在加载时通​​知应用程序的其他部分......也许我会在源代码中找到类似的东西......
    猜你喜欢
    • 2021-03-04
    • 2018-01-04
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 2016-09-19
    • 2021-11-20
    相关资源
    最近更新 更多