尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Moodle Task Indicator 组件详解:在页面上实时展示后台任务进度

发布时间:2026/9/29 7:22:03

资讯中心
01
ARTICLE

Moodle Task Indicator 组件详解:在页面上实时展示后台任务进度

Moodle Task Indicator 组件详解:在页面上实时展示后台任务进度
教育后端前端【免费下载链接】moodleMoodle - the worlds open source learning platform项目地址https://gitcode.com/gh_mirrors/mo/moodle点击查看免费下载导读本文基于 Moodle 官方组件库文档public/admin/tool/componentlibrary/content/moodle/components/task-indicator.md系统讲解 task_indicator 组件的设计原理与完整用法。该组件用于在任意页面展示后台 ad-hoc临时或 scheduled定时任务的执行状态与进度并在任务完成时自动刷新或跳转页面。读完本文你将掌握如何为自定义任务接入存储进度stored progress机制、如何在前端页面渲染指示器、以及如何通过真实源码理解其底层实现对应 Moodle 5.0 及 MDL-81714。什么是 Task IndicatorTask Indicator 是一个进度指示组件用于在任何页面上展示后台正在运行的 ad-hoc 或 scheduled 任务的进度。它解决了一个典型的体验问题当某个后台任务会更新页面内容时如果页面内容已经过期可以把指示器显示在内容原本的位置让用户明白当前内容不是最新任务完成后会自动更新。从源码结构看task_indicator 由三个核心文件构成位于 public/lib 下文件职责lib/amd/src/task_indicator.js前端 AMD 模块监听进度条更新事件进度完成后自动跳转lib/classes/output/task_indicator.phpPHP 渲染类负责查询任务记录、组装模板数据、生成立即运行链接lib/templates/task_indicator.mustacheMustache 模板负责最终 DOM 结构与进度条渲染三者的协作关系是PHP 类负责在服务端判断任务是否存在并导出数据Mustache 模板负责输出 HTMLJS 模块负责异步监控进度条并触发跳转。使用前提stored_progress_task_trait任务类必须使用core\task\stored_progress_task_trait特性task_indicator 才能工作。如果任务类没有使用该 trait构造函数会抛出\coding_exceptionif (!class_uses($task::class, stored_progress_task_trait::class)) { throw new \coding_exception(task_indicator can only be used for tasks using stored_progress_task_trait.); }trait 定义在 lib/classes/task/stored_progress_task_trait.php它提供了三个关键方法initialise_stored_progress()任务入队后调用以 pending待处理状态在数据库stored_progress表中写入一条进度记录使指示器在任务排队期间即可显示start_stored_progress()任务真正开始执行时调用创建进度条并开始记录。注意该方法内部有一个针对 MDL-80770 的处理——手动将渲染器切换为 CLI 渲染器$PAGE-get_renderer(core, null, cli)避免任务在 CLI 环境下运行时的渲染警告get_progress()返回一个core\progress\stored对象供任务在处理记录时上报进度百分比。进度记录的 idnumber 由get_progress_name()生成ad-hoc 任务使用类名_ID因为需要 ID 区分同一任务类的不同实例scheduled 任务仅用类名。最终再经stored_progress_bar::convert_to_idnumber()将类名中的命名空间反斜杠替换为下划线例如\local_something\task\my_task会变成local_something_task_my_task。三步接入从入队到渲染整个接入流程可以概括为入队初始化 → 任务内推进度 → 页面渲染三个步骤下面逐一展开。第一步任务入队时初始化存储进度任务排队后必须立即调用initialise_stored_progress()以便指示器在任务仍处于队列中时就能显示。注意queue_adhoc_task($task, true)的第二个参数为true表示要求返回任务 ID$task new \core\task\mytask($id); $taskid \core\task\manager::queue_adhoc_task($task, true); if ($taskid) { $task-set_id($taskid); $task-initialise_stored_progress(); }从 trait 源码看initialise_stored_progress()会创建一个stored_progress_barautostart: false并调用其store_pending()方法后者会先删除该 idnumber 的旧记录再插入一条timestart为空、message为空的 pending 记录。第二步任务运行时推进进度任务execute()中的典型写法是先start_stored_progress()启动进度记录再获取get_progress()对象每处理一条记录就调用一次progress()最后end_progress()收尾class mytask extends adhoc_task { use \core\task\stored_progress_task_trait; public function execute(): void { $this-start_stored_progress(); $storedprogress $this-get_progress(); foreach ($this-get_records() as $record) { $this-process_record($record); $storedprogress-progress(); } $storedprogress-end_progress(); } }真实案例core_course\task\regrade_final_gradescourse/classes/task/regrade_final_grades.php是官方文档推荐参考的实现。它在execute()中调用start_stored_progress()然后把$this-get_progress()作为$progress参数传给grade_regrade_final_grades()让成绩重算过程边处理边更新存储进度并配合logging_trait记录开始/完成日志。第三步页面渲染指示器任何希望展示任务状态的页面都需要用相同参数创建任务对象实例再交给\core\output\task_indicator$task new mytask($id); $taskindicator new \core\output\task_indicator( task: $task, heading: Task processing, message: get_string(recalculatinggradesadhoc, grades), icon: new \core\output\pix_icon(i/grades, ), redirecturl: $PAGE-url, extraclasses: [mytask], );构造参数一览对应 lib/classes/output/task_indicator.php 的构造函数参数类型默认值说明taskadhoc_task必填其类必须使用stored_progress_task_trait否则抛异常headingstring必填指示器的标题文字messagestring必填解释任务正在做什么的说明文字redirecturl?urlnull任务完成后的跳转地址可省略icon?pix_iconnew pix_icon(i/timer, )标题旁的图标默认是计时器图标extraclassesarray[]附加到指示器容器的额外 CSS 类然后用has_task_record()判断是否存在对应的排队任务实例只有存在时才渲染指示器否则渲染正常内容。grade/report/summary/index.phpgrade/report/summary/index.php就是这么做的——有排队任务时输出指示器没有时输出成绩汇总报告if ($taskindicator-has_task_record()) { echo $OUTPUT-render($taskindicator); } else { $report system_report_factory::create(summary::class, context_course::instance($courseid)); echo $report-output(); }组件背后的实现原理PHP 端查询任务记录与组装数据task_indicator的核心逻辑集中在setup_task_data()方法中通过\core\task\manager::get_queued_adhoc_task_record($this-task)查询匹配的排队任务记录找到记录后用stored_progress_bar::get_by_idnumber()按 idnumber 加载对应的存储进度条在满足以下全部条件时生成立即运行链接runurltool_task插件仍存在array_key_exists(task, plugin_manager::instance()-get_present_plugins(tool))任务尚未开始is_null($this-taskrecord-timestart)cron 当前可运行\core\task\manager::is_runnable()当前用户拥有moodle/site:config系统级权限即管理员。该链接指向admin/tool/task/run_adhoctasks.php?id{任务记录ID}标签文本来自tool_task的语言字符串runnow。export_for_template()负责把内部状态导出为模板上下文并在存在进度条时调用$this-progressbar-init_js()注册前端轮询脚本。模板端DOM 结构与 JS 初始化lib/templates/task_indicator.mustache 的输出结构如下外层容器div classtask-indicator {{extraclasses}}图标core/pix_icon局部模板、h2标题、p消息全部居中显示若存在runurl渲染一个带runlink类和data-idnumber属性的立即运行按钮通过core/progress_bar局部模板渲染进度条模板末尾的{{#js}}块调用 AMD 模块core/task_indicator并传入进度条 idnumber 与跳转 URL。JS 端监听进度并自动跳转lib/amd/src/task_indicator.js 的init(id, redirectUrl)为进度条元素注册update事件监听当进度百分比 0时移除进度条的stored-progress-notstarted类让进度条真正显示出来同时删除页面上的runlink按钮当进度达到100且配置了redirectUrl时等待 2 秒让用户看到进度完成的瞬间后通过window.location.assign(redirectUrl)跳转或刷新页面。值得说明的是进度条本身的数据更新百分比、消息并不是这个 JS 完成的而是由stored_progress模块lib/amd/src/stored_progress.js轮询完成。stored_progress_bar::init_js()只初始化一次该模块通过静态标志$jsloaded去重轮询间隔默认 5 秒可通过配置项$CFG-progresspollinterval调整见 lib/classes/output/stored_progress_bar.php 的get_timeout()。完整示例成绩重算场景将官方文档的模板示例与实际用法结合可以得到一个完整的渲染上下文。假设课程成绩因变更需要异步重算指示器的 Mustache 示例上下文如下{ heading: Regrade in progress, icon: { attributes: [ {name: src, value: /pix/i/timer.svg}, {name: alt, value: } ] }, message: Grades are being recalculated due to recent changes., progress: { id: progressbar_test, message: Task pending, idnumber: progressbar_test, class: stored-progress-bar stored-progress-notstarted, width: 500, value: 0 }, runurl: http://example.com/runtask.php?id1, runlabel: Run now }注意任务刚入队尚未开始时进度条处于stored-progress-notstarted状态、value为0此时管理员能看到Run now按钮一旦任务开始并产生第一次进度更新JS 会立即移除 notstarted 类并隐藏 Run now 按钮进度条开始直观地向前推进。常见问题与注意事项必须使用 traittask_indicator 只能用于使用了stored_progress_task_trait的任务类否则构造即抛\coding_exception。这是最常见的接入错误。渲染与入队参数必须一致页面创建指示器时必须用与入队时完全相同的参数构造任务对象get_queued_adhoc_task_record()才能匹配到正确的任务实例。Run now按钮的可见性该按钮仅对拥有moodle/site:config权限的管理员、且任务尚未开始、cron 可运行、tool_task插件存在时才会出现。它的设计目的是在用户被某个任务阻塞时手动立即运行被跟踪的特定任务实例。跳转时机redirecturl是可选的。设置后页面会在进度到 100% 后延迟约 2 秒自动跳转或刷新不设置则进度条完成后页面保持原样。CLI 环境兼容start_stored_progress()内部会切换到 CLI 渲染器以规避任务在 CLI 下运行的警告stored_progress_bar::start()在非交互式 STDOUT 下也会调用渲染器避免警告。这些细节保证了任务即使通过 CLI cron 运行与页面指示器之间数据同步的稳定性。相关源码索引组件库文档public/admin/tool/componentlibrary/content/moodle/components/task-indicator.md前端模块public/lib/amd/src/task_indicator.js渲染类public/lib/classes/output/task_indicator.php模板public/lib/templates/task_indicator.mustache存储进度 traitpublic/lib/classes/task/stored_progress_task_trait.php存储进度条public/lib/classes/output/stored_progress_bar.php轮询 JSpublic/lib/amd/src/stored_progress.js真实任务示例public/course/classes/task/regrade_final_grades.php真实页面示例public/grade/report/summary/index.php赞分享教育后端前端【免费下载链接】moodleMoodle - the worlds open source learning platform项目地址https://gitcode.com/gh_mirrors/mo/moodle点击查看免费下载相关推荐laravel-admin 定时任务扩展scheduling实战在后台 Web 界面管理 Laravel 计划任务laravel admin 定时任务扩展scheduling实战在后台 Web 界面管理 Laravel 计划任务 导读 本指南讲解 laravel ad后端低代码前端Delon国际化方案轻松支持多语言管理系统Delon国际化方案轻松支持多语言管理系统 Delon作为ng alain的核心模块集提供了一套完整的国际化解决方案帮助开发者轻松构建支持多语言的企业级管BrewUI 的 BrewCLI 封装设计全解析brew 子进程执行、取消与输出捕获指南BrewUI 的 BrewCLI 封装设计全解析brew 子进程执行、取消与输出捕获指南 BrewUI 是 Homebrew 官方推出的 macOS 图形界面桌面应用开发工具上一篇Rusted PackFile Manager 终极指南一篇搞定《全面战争》模组的解析、编辑与诊断下一篇KMS激活工具3分钟搞定Windows和Office永久激活一条命令告别激活水印创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。