【问题标题】:How to show a spinner in Meteor for the duration of an event如何在事件期间在 Meteor 中显示微调器
【发布时间】:2015-11-08 01:25:00
【问题描述】:

在 Meteor 应用程序中,通过单击运行的一项功能需要一段时间才能在某些速度较慢的设备上运行。因此,在这些速度较慢的设备上,应用程序似乎直到功能完成后才执行任何操作。

有问题的函数循环通过一个较大的数组。它不做任何外部事情或方法调用。

为了直观地了解用户,我想向用户显示一个微调器(在慢速设备上)。理想情况下,我会在活动开始时显示微调器,然后在活动结束时移除微调器。但是,如果我对 Meteor 的理解是正确的(并且基于我尝试它时似乎发生的情况),那么在事件期间指定的所有模板更新都只会在事件结束时传播。因此,微调器永远不会显示。

我怎样才能使这项工作按预期进行?

当前设置(使用实际代码编辑):

在 category.html 中:

                    {{#if hasSubCategories}}
                        <a href='#_' id='categorySelect-{{id}}' class='btn categorySelect pull-right
                            {{#if allSubsSelected}}
                                btn-danger
                            {{else}}
                                btn-success 
                            {{/if}}
                        '>{{#if isFlipping}}<span id='spinner-{{id}}'>flip</span>{{/if}}<span class="glyphicon 
                            {{#if allSubsSelected}}
                                glyphicon-remove
                            {{else}}
                                glyphicon-ok
                            {{/if}}
                        " aria-hidden="true"></span></a>
                    {{/if}}

在 category.js 中:

Template.categories.events({
    "click .categorySelect": function (event) {
        Session.set('categorySpinner', this.id);

        categoryFlipper(this.id, function() {
            Session.set('categorySpinner', "");
        });

        return false;
    },
});

Template.categories.helpers({
    allSubsSelected: function() {
        var finder = Categories.find({parentId: this.id});

        var allSelected = true;
        finder.forEach(function(item) {
            if (!($.inArray(item.id, Session.get("categoriesSelected")) !== -1)) {
                allSelected = false;
            }
        });

        return allSelected;
    },
isFlipping: function() {
    if (Session.get("categorySpinner") == this.id)
        return true;
    else
        return false;
}

});

在 main.js 中:

categoryFlipper = function (id, callback) {
    var finder = Categories.find({parentId: id});

    var allSelected = true;
    finder.forEach(function(item) {
        if (!($.inArray(item.id, Session.get("categoriesSelected")) !== -1)) {
            allSelected = false;
        }
    });

    var t = Session.get("categoriesSelected");

    if (allSelected) {
        finder.forEach(function(item) {
            t.splice($.inArray(item.id, t), 1);
        });
    }
    else {
        finder.forEach(function(item) {
            if (!($.inArray(item.id, t) !== -1)) {
                t.push(item.id);
            }
        });         
    }

    Session.set("categoriesSelected", t);

    callback();
}

【问题讨论】:

    标签: events meteor


    【解决方案1】:

    查看您的示例代码(尽管我仍然没有完整的图片,因为我没有看到 allSubsSelectedisFlipping 的帮助程序定义),我很确定您的 categoryFlipper 函数执行如此之快,以至于您从未真正看到微调器。该代码中没有任何内容会真正花费大量时间。你有一个find() 电话,但这并不是真正花费最多时间的事情。这是您的 subscribe() 调用,您通常需要考虑一些延迟,因为数据从数据库拉到浏览器中的 mini-mongo 客户端。

    这样的事情相当普遍:

    {{#unless Template.subscriptionsReady}}
      spinner here...
    {{else}}
      Content here.
    {{/unless}}
    

    这样,当您的订阅触发发布并下拉数据时,Template.subscriptionsReady 返回 false,并显示微调器。请尝试这种方法。

    【讨论】:

    • 谢谢。我试过了,但微调器会拒绝显示,这向我表明,就像在你的示例中一样,“#theButton click”事件将在该事件中的任何更改传播到应用程序之前得到完全处理。而且,这不也是 Meteor 宣传的工作方式吗?
    • 另外,Meteor.call 不是调用服务器上定义的方法吗?我需要调用客户端定义的函数。
    • @MastaBaba 我只是以方法调用为例。您没有发布足够多的代码,所以我不知道后台正在运行什么函数,或者为什么它不能与微调器一起使用。
    • 分享一些实际代码(如果可以的话)而不是伪代码。很有可能,doSomeLongCalculation() 是异步的,这就是您看不到微调器的原因。
    • @MastaBaba 酷,今晚或明天的某个时间我会回复你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 2013-02-08
    相关资源
    最近更新 更多