hellolift学习笔记(8)

随着代码的深入,涉及到的liftweb框架实现级别的代码越来越多,马上完全搞明白实现代码的愿望越来越奢侈,所以后续的笔记将侧重于例子中用到功能的解释,侧重框架的使用,只要不影响理解,尽量不再涉及框架实现层的东西。

9.Create An Entry(2--save)

form提交之后涉及到的过程就是采集数据,写入数据库,更新缓存数据。
采集数据的过程由框架来实现,将采集到的数据封装成一个Entry对象,传递给toform时设定的函数。
写入数据库的过程由BaseMapper.save 方法完成(实际是在Mapper中实现,当然其中很多工作又交给了MetaMapper对象去完成),我们所需要做的就是调用一下save方法,或者如果你愿意的话,在保存的过程中插入你自己想要做的一些事情。
例子中我们能看到afterCommit的使用
// Once the transaction is committed, fill in the blog cache with this entry.
override def afterCommit =
((entry: Entry) => {BlogCache.cache ! AddEntry(entry, entry.author.is)}) :: Nil

,相似的还有以下一些函数可以利用
  def beforeValidation: List[A => Unit] = Nil
def beforeValidationOnCreate: List[A => Unit] = Nil
def beforeValidationOnUpdate: List[A => Unit] = Nil
def afterValidation: List[A => Unit] = Nil
def afterValidationOnCreate: List[A => Unit] = Nil
def afterValidationOnUpdate: List[A => Unit] = Nil

def beforeSave: List[A => Unit] = Nil
def beforeCreate: List[(A) => Unit] = Nil
def beforeUpdate: List[(A) => Unit] = Nil

def afterSave: List[(A) => Unit] = Nil
def afterCreate: List[(A) => Unit] = Nil
def afterUpdate: List[(A) => Unit] = Nil

def beforeDelete: List[(A) => Unit] = Nil
def afterDelete: List[(A) => Unit] = Nil


还有一段代码没有看
override def setFilter = notNull _ :: trim _ :: crop _ :: super.setFilter

说实话,这个命名让我对自己的审美观产生了怀疑,哪位大神居然起了这么个名字!?首先,这不是个set方法,其次他的内容也不同于Iterable中的filter方法,估计他的命名原意是,set之前进行的filter工作。我们来看这个方法的原始定义
/**
* A list of functions that transform the value before it is set. The transformations
* are also applied before the value is used in a query. Typical applications
* of this are trimming and/or toLowerCase-ing strings
*/
protected def setFilter: List[FieldType => FieldType] = Nil

这是一个函数列表,每一个函数都接收一个本类型字段,对其加工之后仍然返回一个本类型字段,用以实现流水线似的转换工作。

这个名字倒是说明白了,这个函数的作用,在每次字段被赋值之前都将被这一系列函数加工。MappedField的子类中各自实现了自己使用的filter。

本例中body字段定义的setFilter使得对body字段有了一些限制,比如说crop方法决定了body的值如果大于构造参数的20000,将被截断,注意,这个行为不仅仅体现是表单提交时,即使是在代码中赋值也一样会被截断。

但是Entry的另一个字段title就稍微有些怪异。
object title extends MappedString(this, 128)

这个怪异在于,MappedString的缺省setFilter中并没有crop方法,所以虽然在toForm过程中maxlength(128)会被用来限制输入框的maxLength,但是如果在代码中赋值的话却不会被截断。

解决这个倒也简单,自己重载setFilter,或者用MappedPoliteString代替MappedString,这个类只干了这一件事(我真觉不出这是一个多好的设计)。

现在,我们也基本搞明白了MappedField构造时this之外参数的作用了。不过这里留下了一个疑问,现在的错误都被系统默默的吞掉了,如何给用户提示呢?

ok,只剩下一点点东西了,我快速的把这个过程close掉。

afterCommit:
在理解了viewblog的过程之后,这个afterCommit之后的处理就没有什么新鲜的了:通知BlogCache,缓存博客内容,通知正在关注这个博客的comet刷新内容。
这里也留下了个小疑问,订阅的comet是被记录在了sessions中,但是如果那个页面关闭,这个sessions中的值是何时被清除的呢?

viewentry:
t.save 之后,将跳转到/veiwentry,BlogUtil.viewentry演示了一种有body的snippet类型,body内容将会作为xhtml参数传递进来。
利用net.liftweb.util.BindHelpers.bind方法把指定namespace的标签值替换为合适的内容。
这里的疑问是,替换时为什么要显示的调用toString方法呢,我尝试去掉toString没有发现什么异常。

BlogUtil还有一个_entryview与DynamicBlogView的同名方法完全一致,怀疑是个小疏忽。

把几个疑问单拎出来:
1.现在的属性字段的错误被系统默默的吞掉了,如何给用户提示呢?
2.订阅的comet是被记录在了sessions中,但是如果那个页面关闭,这个sessions中的值是何时被清除的呢?
3.viewentry替换时为什么要显示的调用toString方法呢,我尝试去掉toString没有发现什么异常。

打完,收工!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值