编辑器服务器端事件
这是介绍 Editor 1.5 新功能的一系列文章中的第二篇。此前,多行编辑 是讨论的重点,而在本文中,我将研究已添加到 PHP 和 .NET 库中的服务器端事件,这些事件可作为 Editor 包的一部分使用,并演示如何将它们用于提高服务器端软件的灵活性。
为什么使用服务器端事件
PHP 和 .NET Editor 服务器端库非常简便,可以创建可读/写表,但可能包含复杂的操作,例如文件上传和连接表,但依然以简单的可读/写操作为根基。对于大型应用程序而言,这是一个良好的开端,但通常还不够——你希望能够根据最终用户执行的数据执行某些操作。
服务器端事件的一个常见示例,也是我们将在下面探讨的一个示例,是将数据更改写入数据库日志表以提供跟踪信息和责任制。另一个示例可能是基于用户输入启动外部进程,例如构建脚本。无论出于何种原因,事件现在在 Editor 中提供了该能力。
如何使用
PHP 和 .NET 库提供的事件在逐行的基础上触发——这一点非常重要,因为 Editor 1.5 具有多行编辑功能。这些事件在创建、编辑或删除行之前立即和之后触发。 beforehand 事件允许修改字段和输入数据,而 afterwards 事件可用于提供已发生该操作的通知。
Editor 库触发以下事件
PHP 名称 | .NET 名称 | 说明 |
---|---|---|
preCreate |
PreCreate |
在创建新行之前立即触发 |
postCreate |
PostCreate |
在创建新行之后立即触发 |
preEdit |
PreEdit |
在更新现有行之前立即触发 |
postEdit |
PostEdit |
在更新现有行之后立即触发 |
preRemove |
PreRemove |
在删除现有行之前立即触发 |
postRemove |
PostRemove |
在删除一行之后立即触发 |
每个事件都有其传入的参数,请参阅 PHP 和 .NET Editor 事件文档,了解这些事件及其选项的完整详细信息。
PHP
PHP 没有本机事件,所以 Editor 库展示了一个对以前使用过 jQuery 的人会立即感到熟悉的一个界面——on()
方法,它接受事件名称作为第一个参数,并接受函数作为第二个参数;这个函数将在触发事件时执行。
例如,考虑以下 Editor 初始化
Editor::inst( $db, 'users' )
->fields(
Field::inst( 'name' ),
Field::inst( 'username' ),
Field::inst( 'password' )
)
->on( 'postCreate', function ( $e, $id, $values, $row ) {
syslog( LOG_INFO, 'New user registered: '.$row['username'] );
} )
->process( $_POST )
->json();
如果您以前使用过Editor PHP 库,那么大部分上述代码都将很熟悉 - 我们有一个包含三个字段的 user
表。此处的有趣部分为 Editor->on()
方法 - 每当创建新用户时,将创建一个 syslog 消息(有关更详细的日志记录,请参见下文)。
使用 PHP 库中的事件就是这么简单 - 监听事件并定义一个可以执行任何所需操作的函数!
.NET
C# 具有内置于语言中的本机 事件处理,并且 Editor 库使用您已经熟悉的这些方法来呈现与其他 C# 库一致的 API。
要侦听事件,只需向您希望收听的事件名称中添加处理程序即可
var editor = new Editor(Db, "users")
.Model<UserModel>();
editor.PostCreate += (sender, e) =>
AppLog( "New user registered: "+(string)e.Values["Username"] );
return Json(
editor.Process(request).Data()
);
其中 AppLog
是将写入文件或数据库的局部函数,而 UserModel
是
public class StaffModel
{
public string Name { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
示例
我们现在知道事件为何有用以及如何在代码中应用它们,所以让我们看一下这些技术的一些应用程序。以下示例均将使用上面定义的简单 users
表,并且只显示事件处理程序代码,因为其他所有内容均可保持不变。
密码字段
对于密码字段,通常仅在最终用户给出新值时,才希望向数据库写入新值。如果没有给出值,则应保留原始值。对于大多数字段来说,这不是问题,因为它们的值可以轻松地从数据库中读取,但对于密码却不是这种情况,您不想(也不应该能够)读取实际值(毕竟应该对它们进行哈希处理 - 您可以使用集合格式设置程序进行处理: PHP - .NET)。
使用 preEdit / PreEdit
事件,我们可以检查用户是否提交了值 - 如果没有,那么我们可以阻止将字段写入,以便密码不被设置为一个空字符串!
PHP
->on( 'preEdit', function ( $e, $id, $values ) {
if ( $values['password'] === '' ) {
$e->field( 'password' )->set( false );
}
} );
.NET
editor.PreEdit += (sender, e) => {
if ( e.Values["Password"] == "" ) {
editor.Field("Password").Set(false);
}
};
电子邮件通知
偶尔,您可能会有一个关键任务表单 - 您向每个字段添加验证,但仍然希望在表上进行编辑时知道,以便您可以监视更改。使用此 post 事件非常容易
PHP
->on( 'postCreate', function ( $editor, $id, $values, $row ) {
mail( 'myself@localhost', 'Row created', 'New row with id '.$id.' created' );
} )
->on( postEdit', function ( $editor, $id, $values, $row ) {
mail( 'myself@localhost', 'Row edited', 'Row with id '.$id.' edited' );
} )
->on( postRemove', function ( $editor, $id, $values ) {
mail( 'myself@localhost', 'Row deleted', 'Row with id '.$id.' deleted' );
} )
.NET
editor.PostCreate += (sender, e) =>
Email( "Row created", "New row with id "+e.id+" created" );
editor.PostEdit += (sender, e) =>
Email( "Row edited", "Row with id "+e.id+" edited" );
editor.PostRemove += (sender, e) =>
Email( "Row deleted", "Row with id "+e.id+" deleted" );
其中函数 Email
可能为(有关更多详细信息,请参见 Scott Gu 的博客)
private void Email( string subject, string message )
{
MailMessage message = new MailMessage();
message.From = new MailAddress("sever@localhost);
message.To.Add(new MailAddress("myself@localhost"));
message.Subject = subject;
message.Body = message;
SmtpClient client = new SmtpClient();
client.Send(message);
}
日志记录
当然,对于更大或更常用的编辑表中,为每行编辑操作获得一封电子邮件消息是不切实际的。但是,能够追踪变更非常重要,在某些情况下甚至是强制性的,这时您可能希望开始考虑将日志信息写入数据库。
同样,由于事件允许执行任何任意函数,因此我们很容易将信息写入数据库,特别是由于 Editor 服务器端库提供了允许轻松执行简单 SQL 命令的数据库方法。
以下仅显示 postEdit / PostEdit
事件,但也可以轻松地将其扩展到创建和删除事件上——插入事件可以移到一个函数中,以确保 DRY。
PHP
->on( 'postEdit', function ( $editor, $id, $values, $row ) {
$editor->db()->insert( 'log', array(
'user' => $_SESSION['username'],
'action' => 'Edit users table row',
'values' => json_encode( $values ),
'row' => $id,
'when' => date('c')
) );
} )
.NET
editor.PostCreate += (sender, e) => db.Insert("log", new Dictionary<string, object>{
{ "user", Session["user_id"] },
{ "action", "Edit users table row" },
{ "values", JsonConvert.SerializeObject( values ) },
{ "row", id },
{ "when", DateTime.Now.ToString("h:mm:ss tt") }
});
结论
这是介绍编辑器 1.5 的三部分系列中的第二个部分——下一个是编辑器 1.5 中可用的表单提交选项。