NotificationPreferences
TsgcHTMLComponent_NotificationPreferences:一张表,每个类别一行,每个通道一个复选框(应用内、推送、电子邮件),适用于 Delphi、C++ Builder 和 .NET。由您的应用加载和保存这些值。
TsgcHTMLComponent_NotificationPreferences:一张表,每个类别一行,每个通道一个复选框(应用内、推送、电子邮件),适用于 Delphi、C++ Builder 和 .NET。由您的应用加载和保存这些值。
库本身不存储任何内容。OnLoadPreferences 向您的应用请求某个用户的值,OnSavePreferences 交回用户勾选的内容,持久化由您负责。这些值是 name=value 键值对,取值为 1 或 0,并且每个提供的键值对始终都存在。它适用于所有版本。
TsgcHTMLComponent_NotificationPreferences(单元 sgcHTML_Component_NotificationPreferences)
一张表:每个类别一行,每个通道一个复选框,外加一个保存按钮
Delphi, C++ Builder, .NET
为用户可以被告知的每一件事,向 Categories 添加一项,用您自己的存储响应 OnLoadPreferences,在 OnSavePreferences 中持久化收到的内容,并把回传的表单路由到 ProcessAction,用户取自会话。
uses
sgcHTML_Session, sgcHTML_Component_NotificationPreferences;
var
oPrefs: TsgcHTMLComponent_NotificationPreferences;
begin
oPrefs := TsgcHTMLComponent_NotificationPreferences.Create(nil);
try
oPrefs.PreferencesID := 'prefs';
oPrefs.Title := 'How you want to hear about it';
oPrefs.SaveCaption := 'Save preferences';
with oPrefs.Categories.Add do
begin
Name := 'orders';
Caption := 'A new order arrives';
end;
with oPrefs.Categories.Add do
begin
Name := 'billing';
Caption := 'A payment fails';
end;
oPrefs.OnLoadPreferences := PrefsLoad;
oPrefs.OnSavePreferences := PrefsSave;
// the user comes from the session, never from the form
oPrefs.LoadPreferences(sgcHTMLRequestSession.UserID);
Response := oPrefs.HTML; // one row per category, one checkbox per channel
finally
oPrefs.Free;
end;
end;
// the application owns the values: one category.channel=1 or =0 per pair
procedure TMain.PrefsLoad(Sender: TObject; const aUserID: string;
aValues: TStrings);
begin
aValues.Add('orders.inapp=1');
aValues.Add('orders.push=0');
aValues.Add('orders.email=1');
end;
procedure TMain.PrefsSave(Sender: TObject; const aUserID: string;
aValues: TStrings);
var
i: Integer;
begin
// every offered pair is here, with 1 or 0
for i := 0 to aValues.Count - 1 do
MyStore.Save(aUserID, aValues.Names[i], aValues.Values[aValues.Names[i]] = '1');
end;
// in the message handler that receives the form the table posts
if oPrefs.ProcessAction(vUser, vAction, vPostedFields) then
oHTMX.PushFragment(vGuid, oPrefs.HTML);
// includes: sgcHTML_Session.hpp, sgcHTML_Component_NotificationPreferences.hpp
TsgcHTMLComponent_NotificationPreferences *oPrefs = new TsgcHTMLComponent_NotificationPreferences(NULL);
try
{
oPrefs->PreferencesID = "prefs";
oPrefs->Title = "How you want to hear about it";
oPrefs->SaveCaption = "Save preferences";
TsgcHTMLPreferenceCategory *orders = oPrefs->Categories->Add();
orders->Name = "orders";
orders->Caption = "A new order arrives";
TsgcHTMLPreferenceCategory *billing = oPrefs->Categories->Add();
billing->Name = "billing";
billing->Caption = "A payment fails";
oPrefs->OnLoadPreferences = PrefsLoad;
oPrefs->OnSavePreferences = PrefsSave;
// the user comes from the session, never from the form
oPrefs->LoadPreferences(sgcHTMLRequestSession()->UserID);
String html = oPrefs->HTML; // one row per category, one checkbox per channel
}
__finally
{
delete oPrefs;
}
// the application owns the values: one category.channel=1 or =0 per pair
void __fastcall TMain::PrefsLoad(TObject *Sender, const String aUserID,
TStrings *aValues)
{
aValues->Add("orders.inapp=1");
aValues->Add("orders.push=0");
aValues->Add("orders.email=1");
}
void __fastcall TMain::PrefsSave(TObject *Sender, const String aUserID,
TStrings *aValues)
{
// every offered pair is here, with 1 or 0
for (int i = 0; i < aValues->Count; i++)
MyStore->Save(aUserID, aValues->Names[i], aValues->Values[aValues->Names[i]] == "1");
}
// in the message handler that receives the form the table posts
if (oPrefs->ProcessAction(vUser, vAction, vPostedFields))
oHTMX->PushFragment(vGuid, oPrefs->HTML);
using esegece.sgcWebSockets;
var prefs = new TsgcHTMLComponent_NotificationPreferences();
prefs.PreferencesID = "prefs";
prefs.Title = "How you want to hear about it";
prefs.SaveCaption = "Save preferences";
var orders = prefs.Categories.Add();
orders.Name = "orders";
orders.Caption = "A new order arrives";
var billing = prefs.Categories.Add();
billing.Name = "billing";
billing.Caption = "A payment fails";
prefs.OnLoadPreferences += PrefsLoad;
prefs.OnSavePreferences += PrefsSave;
// the user comes from the session, never from the form
string user = sgcHTMLSessionHelpers.sgcHTMLRequestSession()?.UserID ?? "";
prefs.LoadPreferences(user);
string html = prefs.HTML; // one row per category, one checkbox per channel
// the application owns the values: one category.channel=1 or =0 per pair
void PrefsLoad(object sender, string userID, List<string> values)
{
values.Add("orders.inapp=1");
values.Add("orders.push=0");
values.Add("orders.email=1");
}
void PrefsSave(object sender, string userID, List<string> values)
{
// every offered pair is here, with 1 or 0
foreach (var line in values)
{
int eq = line.IndexOf('=');
myStore.Save(userID, line.Substring(0, eq), line.Substring(eq + 1) == "1");
}
}
// in the message handler that receives the form the table posts
if (prefs.ProcessAction(user, action, postedFields))
htmx.PushFragment(guid, prefs.HTML);
您最常使用的成员。
Categories 是一个 TsgcHTMLPreferenceCategories 集合;每个 TsgcHTMLPreferenceCategory 有一个 Name,即值中使用的稳定键,也是复选框的名称,还有一个 Caption,即用户看到的文字,渲染时会被转义。空的 Caption 会回退为 Name,Name 为空的类别会被跳过。IndexOfName 用于查找某一个。
Channels 选择 ncInApp、ncPush 和 ncEmail 中哪些拥有一列,默认三个都有。通道名称与 TsgcHTMLComponent_Notification 共用,后者在投递任何内容之前,会通过 OnGetChannel 向您的应用询问这些通道。
值是 name=value 键值对,每个提供的类别和通道各一个:orders.inapp=1、orders.push=0、orders.email=1。键由类别的 Name、一个点和通道键 inapp、push 或 email 组成。通道开启时值为 1,关闭时为 0。ValueKey(aCategory, aChannel) 用于构建该键。
LoadPreferences(aUserID) 清空 Values 并触发 OnLoadPreferences(aUserID, aValues):请向 aValues 填入该用户的 category.channel=1 行。Values 是当前渲染内容或最近一次保存内容的只读视图。您省略的键值对显示为未勾选。
OnSavePreferences(aUserID, aValues) 会收到每个提供的键值对及其新值,因此您的应用无需猜测缺失的键是什么意思。SavePreferences(aUserID, aPosted) 接收原样到达的表单(其中只有被勾选的复选框存在),ProcessAction(aUserID, aAction, aPosted) 负责路由,并返回 False(当操作不是 prefsSave 时)。
保存的表单作为客户端发送的数据传输,因此标记中不会写入任何用户 id,任何指向组件未提供的类别或通道的内容都会被忽略。伪造的表单无法扩大偏好设置的范围。组件不执行任何授权:请从请求会话(sgcHTMLRequestSession)中获取执行操作的用户,绝不要从表单中获取。
IsChecked(aCategory, aChannel) 告知某个键值对是否开启,SetChecked(aCategory, aChannel, aValue) 把 1 或 0 写入 Values,当类别存在且该通道有对应的列时,IsOffered(aCategory, aChannel) 为 True。
PreferencesID 是根元素的 id,也是在 prefs 字段中回传的值,因此包含多个表的页面能知道是哪一个作出的响应。Title、SaveCaption 和 EmptyText 设置文本,ShowSave(默认开启)显示按钮。该表单回传 prefsSave,形式为 data-sgc-ws-send 表单,每个被勾选的复选框对应一个 category.channel 字段,其值设为 1。
该单元在定义了 SGC_HTML 时编译,sgcVer.inc 不会为 Android 和 iOS 定义它。它适用于所有版本,sgcHTML 是独立的包,与 sgcWebSockets 分开销售。推送复选框只记录一个选择:要投递推送需要 WebPush,它仅在 Enterprise 和 All-Access 版本中提供。
通知本身由 NotificationInbox 显示,而 Notification 决定是在页面中还是通过推送告知用户。