NotificationInbox

TsgcHTMLComponent_NotificationInbox:一个带有未读徽章的铃铛和一个显示某个用户通知的下拉列表,适用于 Delphi、C++ Builder 和 .NET。记录由您的应用保存,组件负责渲染它们。

TsgcHTMLComponent_NotificationInbox

库本身不存储任何内容。您的应用用它保存的记录来响应 OnLoadNotifications,并通过 OnMarkReadOnMarkAllRead 得知用户做了什么,以便持久化。组件只渲染界面,不执行任何授权。它适用于所有版本,可通过 WebSocket 或服务器发送事件工作。

组件类

TsgcHTMLComponent_NotificationInbox(单元 sgcHTML_Component_NotificationInbox

渲染为

Bootstrap 下拉框标记:一个铃铛、一个未读徽章和一个列表

语言

Delphi, C++ Builder, .NET

创建它,处理三个事件,路由操作

给收件箱设置 InboxID,在 OnLoadNotifications 中用您自己的存储填充它,在 OnMarkReadOnMarkAllRead 中持久化用户所做的操作,并把回传的操作路由到 ProcessAction,用户取自会话。

uses
  sgcHTML_Session, sgcHTML_Component_NotificationInbox;

var
  oInbox: TsgcHTMLComponent_NotificationInbox;
begin
  oInbox := TsgcHTMLComponent_NotificationInbox.Create(nil);
  try
    oInbox.InboxID := 'inbox';
    oInbox.Title := 'Notifications';
    oInbox.MaxItems := 10;
    oInbox.OnLoadNotifications := InboxLoad;
    oInbox.OnMarkRead := InboxMarkRead;
    oInbox.OnMarkAllRead := InboxMarkAllRead;

    // the user comes from the session, never from the form
    oInbox.LoadNotifications(sgcHTMLRequestSession.UserID);
    Response := oInbox.HTML;   // bell, unread badge and dropdown
  finally
    oInbox.Free;
  end;
end;

// the application owns the rows: fill the list, newest first
procedure TMain.InboxLoad(Sender: TObject; const aUserID: string;
  aList: TsgcHTMLInboxItems);
begin
  with aList.Add do
  begin
    Id := '1042';
    Title := 'New order';
    Text := 'Order #1042 was placed.';
    Timestamp := '2 min ago';
    Read := False;
  end;
end;

procedure TMain.InboxMarkRead(Sender: TObject; const aUserID,
  aNotificationID: string);
begin
  // persist it, after checking that aUserID owns aNotificationID
end;

// in the message handler that receives the actions the inbox posts
if oInbox.ProcessAction(vUser, vAction, vNotificationID) then
  oHTMX.PushFragment(vGuid, oInbox.GetListFragmentHTML +
    oInbox.GetBadgeFragmentHTML);
// includes: sgcHTML_Session.hpp, sgcHTML_Component_NotificationInbox.hpp

TsgcHTMLComponent_NotificationInbox *oInbox = new TsgcHTMLComponent_NotificationInbox(NULL);
try
{
  oInbox->InboxID = "inbox";
  oInbox->Title = "Notifications";
  oInbox->MaxItems = 10;
  oInbox->OnLoadNotifications = InboxLoad;
  oInbox->OnMarkRead = InboxMarkRead;
  oInbox->OnMarkAllRead = InboxMarkAllRead;

  // the user comes from the session, never from the form
  oInbox->LoadNotifications(sgcHTMLRequestSession()->UserID);
  String html = oInbox->HTML;   // bell, unread badge and dropdown
}
__finally
{
  delete oInbox;
}

// the application owns the rows: fill the list, newest first
void __fastcall TMain::InboxLoad(TObject *Sender, const String aUserID,
  TsgcHTMLInboxItems *aList)
{
  TsgcHTMLInboxItem *item = aList->Add();
  item->Id = "1042";
  item->Title = "New order";
  item->Text = "Order #1042 was placed.";
  item->Timestamp = "2 min ago";
  item->Read = false;
}

void __fastcall TMain::InboxMarkRead(TObject *Sender, const String aUserID,
  const String aNotificationID)
{
  // persist it, after checking that aUserID owns aNotificationID
}

// in the message handler that receives the actions the inbox posts
if (oInbox->ProcessAction(vUser, vAction, vNotificationID))
  oHTMX->PushFragment(vGuid, oInbox->GetListFragmentHTML() +
    oInbox->GetBadgeFragmentHTML());
using esegece.sgcWebSockets;

var inbox = new TsgcHTMLComponent_NotificationInbox();
inbox.InboxID = "inbox";
inbox.Title = "Notifications";
inbox.MaxItems = 10;
inbox.OnLoadNotifications += InboxLoad;
inbox.OnMarkRead += InboxMarkRead;
inbox.OnMarkAllRead += InboxMarkAllRead;

// the user comes from the session, never from the form
string user = sgcHTMLSessionHelpers.sgcHTMLRequestSession()?.UserID ?? "";
inbox.LoadNotifications(user);
string html = inbox.HTML;   // bell, unread badge and dropdown

// the application owns the rows: fill the list, newest first
void InboxLoad(object sender, string userID, TsgcHTMLInboxItems list)
{
    var item = list.Add();
    item.Id = "1042";
    item.Title = "New order";
    item.Text = "Order #1042 was placed.";
    item.Timestamp = "2 min ago";
    item.Read = false;
}

void InboxMarkRead(object sender, string userID, string notificationID)
{
    // persist it, after checking that userID owns notificationID
}

// in the message handler that receives the actions the inbox posts
if (inbox.ProcessAction(user, action, notificationId))
    htmx.PushFragment(guid, inbox.GetListFragmentHTML() + inbox.GetBadgeFragmentHTML());

关键属性与方法

您最常使用的成员。

Items

Items 是一个 TsgcHTMLInboxItems 集合;每个 TsgcHTMLInboxItem 都有 IdTitleTextTimestampUrlIconRead。记录中的所有内容都是数据,渲染时会被转义,包括 Icon:请传入字面字符,不要传入 HTML 实体或标记。Url 会经过净化,javascript:data: 链接会被拒绝。

存储事件

组件只保存它正在渲染的内容。OnLoadNotifications(aUserID, aList) 触发时 aList 已被清空:请用该用户的通知填充它,最新的在前。OnMarkRead(aUserID, aNotificationID) 在条目被标记为已读之后触发,OnMarkAllRead(aUserID) 在所有条目都被标记之后触发。

服务器端操作

LoadNotifications(aUserID)MarkRead(aUserID, aNotificationID)MarkAllRead(aUserID) 负责实际工作。ProcessAction(aUserID, aAction, aNotificationID) 把一条回传的操作路由给合适的那个,当该操作不是收件箱操作时返回 False,因此您可以继续查找它的所有者。

它回传的操作

下拉框回传 inboxMarkRead(字段 actioninboxid)、inboxMarkAllReadinboxRefresh(字段 actioninbox),形式为 data-sgc-ws-send 表单。inbox 字段携带渲染该表单的收件箱的元素 id,设置了 InboxID 时就是它,包含多个收件箱的页面正是靠它把操作路由到正确的组件。

授权

组件只渲染界面,不执行任何授权。每个操作都作为客户端发送的数据传输,因此恶意客户端可以伪造任何操作和任何通知 id。标记中不会写入任何用户 id:请从请求会话(sgcHTMLRequestSession)中获取执行操作的用户,绝不要从表单中获取,并且在持久化任何内容之前,先检查该用户是否拥有所收到的通知 id。

外观

Title 是下拉框的标题,EmptyText 是没有内容可显示时的占位文本,BellIcon 是触发器字符,默认是带有 HTML 实体的受信任标记。MaxItems 限制可见行数(默认 10,0 表示全部显示),ShowMarkAllReadShowBadge 默认开启,AddNotification(aId, aTitle, aText, aTimestamp, aUrl, aIcon) 添加一行,或更新具有相同 id 的那一行。

实时更新

每条通知、徽章和列表都带有稳定的元素 id。发生一次变更后,只需用 GetItemFragmentHTML(aId)GetBadgeFragmentHTMLGetListFragmentHTML 渲染受影响的标记,并通过 TsgcHTMX_Engine_Server.PushFragmentBroadcastFragment 推送,而不必重新渲染整个页面。UnreadCount 统计 ReadFalse 的条目数。

版本与通道

该单元在定义了 SGC_HTML 时编译,sgcVer.inc 不会为 Android 和 iOS 定义它。它适用于所有版本,可通过 WebSocket 或服务器发送事件工作。sgcHTML 是独立的包,与 sgcWebSockets 分开销售。

页面或推送

收件箱本身不在页面和推送之间做选择:这由 TsgcHTMLComponent_Notification 完成,参见 NotificationWebPush。每个用户希望使用哪些通道,在 NotificationPreferences 中设置。

继续探索

在线帮助此组件的完整 API 参考和使用指南。
所有 sgcHTML 组件浏览 80 多个组件的完整功能矩阵。
下载免费试用版30 天试用版包含 60.HTML 演示项目,其中 17.FieldService 使用了收件箱。
价格Single、Team 和 Site 授权,均含完整源代码。
超值之选:All-AccesseSeGeCe 全部产品,含高级支持,每年 €1,059 起。
查看 All-Access 价格

准备好开始了吗?

下载免费试用版,开始在 Delphi、C++ Builder 和 .NET 中构建 Web 界面。