rails的画面标签虽说已经基本够用了,
但是总也会有实现起来不方便的地方,
这时候就需要用到自定义标签了。
为了防止盗链,先把原文地址贴出来
http://blog.csdn.net/zhao_hongsheng/archive/2011/05/09/6406996.aspx
想要自定义标签就得能看懂rails的源码。
(在网上搜索了一下,中文资料太少了,还是自己看吧)
写出来各位网友分享一下。
rails版本 | 2.3.8 |
---|
path: rails/actionpack/lib/action_view/helpers
相关文件 |
---|
form_helper.rb form_tag_helper.rb form_options_helper.rb tag_helper.rb form_helper.rb |
主要从2标签入手form_tag,form_for 其他就好办了。
看源码,先读注释!!
在form_helper.rb开头看到
说明form_tag标签用到的方法基本都定义在form_tag_helper.rb文件中
form_for标签用到的方法都定义在form_helper.rb文件中。
先看个简单的form_tag_helper.rb
打开一看,所有用的方法都定义在里面了。
比如这个text_field_tag标签,
里面调用tag_helper.rb中的tag方法实现了标签的输出。
很简单嘛~,但是实际中大多用的还是form_for标签。
这个用点儿小难度,follow me ~
打开form_helpler.rb文件,找到form_for的定义
这句先把<form action="xxxx" method="xx" ....>等内容生成好
然后关键的调用了个fields_for方法,来生成form标签里面的内容
找到这个方法的定义,还是在这个文件里
注意最后2行,实例化了一个ActionView::Base.default_form_builder的对象,
这个对象就是我们经常用到的
中的 f 变量了,
那么这个f 到底是什么类的对象呢?
看form_helper.rb的最后
原来是ActionView::Helpers::FormBuilder类型的对象。
那么 <%= f.text_field .....%>就是调用的
FormBuilder类中的相应的text_field方法喽~
有代码为证,这个类里确实定义了这些方法
这里要注意的是
又是class_eval,ruby的黑魔法(black magic)
除了label check_box radio_button fields_for这四个方法
所有form_helper module里的实例方法都被重新定义了,
当然这四个方法随后也都被重写了,
之所以分开写只程序技巧上的问题,
但却增加了阅读的难度。
下面具体看这些方法是怎么被重写的。
@template.send,调用了@template这个对象的相应的方法,
可以看出其实FormBuilder中的这些方法只是做了一个代理,
终究还是调用了,FormHelper中定义的方法,
好处就是f.text_field的时候不用传@object这个参数了。
@template就是self,也就是Active::View::Base的实例对象,
没看懂?仔细看看FormBuilder的initialize方法,你行的!
现在问题简化了,只要去看FormHelper中关于标签的方法如何定义的就好啦,
拿text_field举例
调用了,InstanceTag类的to_input_field_tag方法,
to_input_field_tag中还是调用tag_helper.rb中(Tag类)的tag方法输出标签。
到这里就已经理清了整个标签输出的过程。
之后标签自定义什么的,随你了~
顺便提一下,标签输出的ActiveRecord值都是before_type_cast的
before_type_cast是什么不知道?那得补一下ActiveRecord相关知识了,
有空儿我再写上来。
也许还有的网友跟我有同样的疑问
select方法的定义在FormBuilder里怎么找不到?
用IDE在全局搜索下,发现在form_options_helper.rb下还有定义。。
完。。。
第一次写源码解读,若有错误,欢迎指正探讨~