如何实现Django-notifications-hq通知标记已读并实时更新
问题描述
基于Django-notifications-hq实现通知功能,已重写fill_notification_list为自定义的streamshiv_notify函数,能正常在模板展示通知。现在需要实现点击告警下拉框按钮时,将所有通知标记为已读(unread=False)并实时更新列表。已写出基础点击事件代码,但不清楚后续处理逻辑:
$('.sh-alert-btn').on('click touch', function(){ $.get('{% url "notifications:mark_all_as_read" %}', function(response) { }); });
自定义的streamshiv_notify函数如下:
function streamshiv_notify(data) { var menus = document.getElementsByClassName('live_notify_list'); if (menus) { var messages = data.unread_list.map(function (item) { if(typeof item.verb !== 'undefined'){ message = message + '<h6>' + item.verb + "</h6>"; } if(typeof item.timestamp !== 'undefined'){ message = message + '<p>' + new Date(item.timestamp).toLocaleDateString('en-US', { day: 'numeric', month: 'short', year: 'numeric', }); + '</p>'; } var unread = ((item.unread) ? 'unread' : 'read'); return '<li class="' + unread + '">' + message + '</li>'; }).join('') for (var i = 0; i < menus.length; i++){ menus[i].innerHTML = messages; } } }
插件提供的API URL包括:
{% url 'notifications:live_unread_notification_count' %} {% url 'notifications:live_all_notification_count' %} {% url 'notifications:live_unread_notification_list' %} {% url 'notifications:live_all_notification_list' %}
解决方案
1. 完善点击事件逻辑
点击按钮后,先请求mark_all_as_read接口完成标记操作,成功后重新拉取最新的未读通知列表,再调用自定义的streamshiv_notify函数更新页面UI。
修改后的点击事件代码:
$('.sh-alert-btn').on('click touch', function(){ // 先请求标记所有通知为已读 $.get('{% url "notifications:mark_all_as_read" %}', function() { // 标记成功后,拉取最新的未读通知数据 $.get('{% url "notifications:live_unread_notification_list" %}', function(data) { // 调用自定义函数更新通知列表UI streamshiv_notify(data); // 可选:如果页面有未读数量角标,同步更新 // $.get('{% url "notifications:live_unread_notification_count" %}', function(count) { // $('.unread-badge').text(count); // }); }); }).fail(function() { // 请求失败时提示用户 alert('标记已读失败,请稍后重试'); }); });
2. 修复自定义函数的bug
原streamshiv_notify函数中message变量未初始化,会导致JS报错,同时日期格式化代码有语法错误,需要调整:
function streamshiv_notify(data) { var menus = document.getElementsByClassName('live_notify_list'); if (menus) { var messages = data.unread_list.map(function (item) { // 初始化message变量,避免未定义报错 var message = ''; if(typeof item.verb !== 'undefined'){ message += '<h6>' + item.verb + "</h6>"; } if(typeof item.timestamp !== 'undefined'){ message += '<p>' + new Date(item.timestamp).toLocaleDateString('en-US', { day: 'numeric', month: 'short', year: 'numeric', }) + '</p>'; // 移除多余的分号 } var unread = item.unread ? 'unread' : 'read'; return '<li class="' + unread + '">' + message + '</li>'; }).join('') for (var i = 0; i < menus.length; i++){ menus[i].innerHTML = messages; } } }
3. 可选优化:防止重复点击
添加loading状态,避免用户短时间内重复触发请求:
$('.sh-alert-btn').on('click touch', function(){ var $btn = $(this); // 如果按钮处于loading状态,直接返回 if ($btn.hasClass('loading')) return; $btn.addClass('loading'); $.get('{% url "notifications:mark_all_as_read" %}', function() { $.get('{% url "notifications:live_unread_notification_list" %}', function(data) { streamshiv_notify(data); $btn.removeClass('loading'); }); }).fail(function() { alert('标记已读失败,请稍后重试'); $btn.removeClass('loading'); }); });
内容的提问来源于stack exchange,提问作者Jonathan Sumner
相关产品推荐
相关产品推荐

