返回介绍

进度通知

发布于 2025-01-02 21:54:01 字数 4665 浏览 0 评论 0 收藏 0

为了完善这个功能,我想在后台任务运行时提醒用户任务完成的百分比进度。 在浏览 Bootstrap 组件选项时,我决定在导航栏的下方使用一个 Alert 组件。 Alert 组件是向用户显示信息的带颜色的横条。 我用蓝色的 Alert 框来渲染闪现的消息。 现在我要添加一个绿色的 Alert 框来显示任务进度。 样式如下:

app/templates/base.html :基础模板中的导出进度 Alert 组件。

...
{% block content %}
    <div>
        {% if current_user.is_authenticated %}
        {% with tasks = current_user.get_tasks_in_progress() %}
        {% if tasks %}
            {% for task in tasks %}
            <div role="alert">
                {{ task.description }}
                <span id="{{ task.id }}-progress">{{ task.get_progress() }}</span>%
            </div>
            {% endfor %}
        {% endif %}
        {% endwith %}
        {% endif %}
        ...
{% endblock %}
...

渲染任务 Alert 组件的方法几乎与闪现消息相同。 外部条件在用户未登录时跳过所有与 Alert 相关的标记。而对于已登录用户,我通过调用前面创建的 get_tasks_in_progress() 方法来获取当前正在进行的任务列表。 在当前版本的应用中,我最多只能得到一个结果,因为我不允许多个导出任务同时执行,但将来我可能要支持可以共存的其他类型的任务,所以以通用的方式渲染 Alert 可以节省我以后的时间。

对于每项任务,我都会在页面上渲染一个 Alert 元素。 Alert 的颜色由第二个 CSS 样式控制,本处是 alert-success ,而在闪现消息是 alert-infoBootstrap 文档 包含有关 Alert 的 HTML 结构的详细信息。 Alert 文本包括存储在 Task 模型中的 description 字段,后面跟着完成百分比。

百分比被封装在具有 id 属性的 <span> 元素中。 原因是我要在收到通知时用 JavaScript 刷新百分比。 我给任务 ID 末尾附加 -progress 来构造 id 属性。 当有通知到达时,通过其中的任务 ID,我可以很容易地使用 #<task.id>-progress 选择器找到正确的 <span> 元素来更新。

如果你此时进行尝试,则每次导航到新页面时都会看到“静态”的进度更新。 你可以注意到,在启动导出任务后,你可以自由导航到应用程序的不同页面,正在运行的任务的状态始终都会展示出来。

为了对 span> 元素的百分比的动态更新做准备,我将在 JavaScript 端编写一个辅助函数:

app/templates/base.html :动态更新任务进度的辅助函数。

...
{% block scripts %}
    ...
    <script>
        ...
        function set_task_progress(task_id, progress) {
            $('#' + task_id + '-progress').text(progress);
        }
    </script>
    ...
{% endblock %}

这个函数接受一个任务 id 和一个进度值,并使用 jQuery 为这个任务定位 <span> 元素,并将新进度作为其内容写入。 实际上不需要验证页面上是否存在该元素,因为如果没有找到该元素,jQuery 将不会执行任何操作。

app/tasks.py 中的 _set_task_progress() 函数每次更新进度时调用 add_notification() ,就会产生新的通知。 而我在 第二十一章 明智地以完全通用的方式实现了通知功能。 所以当浏览器定期向服务器发送通知更新请求时,浏览器会获得通过 add_notification() 方法添加的任何通知。

但是,这些 JavaScript 代码只能识别具有 unread_message_count 名称的那些通知,并忽略其余部分。 我现在需要做的是扩展该函数,通过调用我上面定义的 set_task_progress() 函数来处理 task_progress 通知。 以下是处理通知更新版本 JavaScript 代码:

app/templates/base.html :通知处理器。

                        for (var i = 0; i < notifications.length; i++) {
                            switch (notifications[i].name) {
                                case 'unread_message_count':
                                    set_message_count(notifications[i].data);
                                    break;
                                case 'task_progress':
                                    set_task_progress(
                                        notifications[i].data.task_id,
                                        notifications[i].data.progress);
                                    break;
                            }
                            since = notifications[i].timestamp;
                        }

现在我需要处理两个不同的通知,我决定用一个 switch 语句替换检查 unread_message_count 通知名称的 if 语句,该语句包含我现在需要支持的每个通知。 如果你对“C”系列语言不熟悉,就可能从未见过 switch 语句,它提供了一种方便的语法,可以替代一长串的 if/elseif 语句。这是一个很棒的特性,因为当我需要支持更多通知时,只需简单地添加 case 块即可。

回顾一下,RQ 任务附加到 task_progress 通知的数据是一个包含两个元素 task_idprogress 的字典,这两个元素是我用来调用 set_task_progress() 的两个参数。

如果你现在运行该应用,则绿色 Alert 框中的进度指示器将每 10 秒刷新一次(因为刷新通知的时间间隔是 10 秒)。

由于本章介绍了新的可翻译字符串,因此需要更新翻译文件。 如果你要维护非英语语言文件,则需要使用 Flask-Babel 刷新翻译文件,然后添加新的翻译:

(venv) $ flask translate update

如果你使用的是西班牙语翻译,那么我已经为你完成了翻译工作,因此可以从 下载包 中提取 app/translations/es/LC_MESSAGES/messages.po 文件,并将其添加到你的项目中。

翻译文件到位后,还要编译翻译文件:

(venv) $ flask translate compile

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文