随着代码的深入,涉及到的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没有发现什么异常。
打完,收工!
分享到:
相关推荐
Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习笔记Java学习...
希沃白板学习笔记.pdf希沃白板学习笔记.pdf希沃白板学习笔记.pdf希沃白板学习笔记.pdf希沃白板学习笔记.pdf希沃白板学习笔记.pdf希沃白板学习笔记.pdf希沃白板学习笔记.pdf希沃白板学习笔记.pdf
Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Springcloud学习笔记.md,Spring...
人工智能学习笔记,人工智能学习笔记,人工智能学习笔记人工智能学习笔记,人工智能学习笔记,人工智能学习笔记人工智能学习笔记,人工智能学习笔记,人工智能学习笔记人工智能学习笔记,人工智能学习笔记,人工智能...
CCNA学习笔记 CCNA学习笔记 CCNA学习笔记
云的学习笔记-云的学习笔记系统-云的学习笔记系统源码-云的学习笔记管理系统-云的学习笔记管理系统java代码-云的学习笔记系统设计与实现-基于ssm的云的学习笔记系统-基于Web的云的学习笔记系统设计与实现-云的学习...
云的学习笔记-云的学习笔记系统-云的学习笔记系统源码-云的学习笔记管理系统-云的学习笔记管理系统java代码-云的学习笔记系统设计与实现-基于ssm的云的学习笔记系统-基于Web的云的学习笔记系统设计与实现-云的学习...
nginx学习笔记(软件+学习笔记) 仅供学习交流! 后续会持续分享相关资源,记得关注哦! nginx学习笔记(软件+学习笔记) 仅供学习交流! 后续会持续分享相关资源,记得关注哦! nginx学习笔记(软件+学习笔记) ...
2022吴恩达机器学习笔记汇总(共10章节).zip2022吴恩达机器学习笔记汇总(共10章节).zip2022吴恩达机器学习笔记汇总(共10章节).zip2022吴恩达机器学习笔记汇总(共10章节).zip2022吴恩达机器学习笔记汇总(共10章节).zip...
docker学习笔记,docker学习笔记,docker学习笔记,docker学习笔记,docker学习笔记,docker学习笔记,docker学习笔记,docker学习笔记,docker学习笔记,docker学习笔记,docker学习笔记,docker学习笔记,docker学习笔记,...
PHP个人学习笔记
Contiki学习笔记:进程、事件、etimer关系 Contiki 实例: Contiki学习笔记:创建两个交互进程 Contiki 主函数剖析: Contiki学习笔记:main函数剖析 Contiki学习笔记:启动一个进程process_start Contiki学习笔记...
ssh学习笔记1 ssh学习笔记1 ssh学习笔记1 ssh学习笔记1 ssh学习笔记1 ssh学习笔记1 ssh学习笔记1
java学习笔记java学习笔记.zipjava学习笔记.zipjava学习笔记.zipjava学习笔记.zipjava学习笔记.zipjava学习笔记.zipjava学习笔记.zipjava学习笔记.zipjava学习笔记.zipjava学习笔记.zipjava学习笔记.zipjava学习笔记...