- 浏览: 105190 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
tiroc:
liushooter 写道灰常感谢 tiroc
Monkey Patch让Paperclip支持中文名称的文件上传 -
liushooter:
灰常感谢 tiroc
Monkey Patch让Paperclip支持中文名称的文件上传 -
tiroc:
snjxiaojing 写道原来如此,谢大哥~~~
Ubuntu下设置Sublime Text 2汉字显示 -
snjxiaojing:
原来如此,谢大哥~~~
Ubuntu下设置Sublime Text 2汉字显示 -
tiroc:
snjxiaojing 写道tiroc 写道snjxiaoji ...
Ubuntu下设置Sublime Text 2汉字显示
Rails 3 Client Side Validations 工作机制备忘
- 博客分类:
- Ruby on Rails
- JavaScript
最近看了一下 Client Side Validations 这个插件 JavaScript 部分的源码,记录一下对它的理解(版本为 Rails 3 Client Side Validations - v3.1.0 )。
一、客户端校验的设置信息
首先,来看一下它是通过什么方式在客户端得到校验规则的。在页面渲染的时候,client_side_validations 会在 FormBuilder 输出的表单 HTML 后边附加一段 JavaScript,内容看起来像是这样:
这段 JavaScript 使用了表单 id 作为一个全局变量的名字(本文中为 new_article),来存储这个表单的校验配置信息。下面,我先解释一下这个全局变量的属性:
在 client_side_validations 的源码中,把前边说的这个全局变量称为 settings,下面我为了描述方便,也这么叫它。所以在本文中我说到 settings 时请想到 window['new_article']。
二、client_side_validations 中的 validators
在说到整个插件的工作流程之前,我们先把前边说的 settings 中的 validators 属性和 client_side_validations 源码中的校验函数对应起来看一下:
我把每个函数的的具体实现去掉了,这样就可以很容易的看出 settings 的 validators 所包含的,就是此处这些校验函数的名字。没错,在执行校验的时候,就是通过 settings 中的那些名字来找到这些函数并进行调用的。
三、client_side_validations 中的 formBuilders
在这个地方只做两件事——在页面中显示错误信息(add 函数)和去掉错误信息(remove 函数)。这几对 add、remove 函数只是在不同的 FormBuilder 下的不同实现而已。在表单项校验完毕时,根据 settings 的 type 属性来调用这里对应的 add() 或者 remove()。
四、client_side_validations 中的 callbacks
这个部分的代码,我没做删减,可以看出 client_side_validations 只使用了两个 callback,其余都是预留的。如果想设置 callback 可以这样做:
五、整体流程和 $.fn.validate 等主要函数
有了前面几个部分的铺垫,client_side_validations 的工作流程就好理解多了,下面我把对应的源码细节替换成注释,来大概理顺一下代码:
基本就是这样了。
最后做个广告 《JavaScript语言精粹》、《基于MVC的JavaScript Web富应用开发》,这两本书对于我这种写JS都是用哪儿查哪儿,没系统学过JS的人帮助很大。
一、客户端校验的设置信息
首先,来看一下它是通过什么方式在客户端得到校验规则的。在页面渲染的时候,client_side_validations 会在 FormBuilder 输出的表单 HTML 后边附加一段 JavaScript,内容看起来像是这样:
window['new_article'] = { "type": "SimpleForm::FormBuilder", "error_class": ["error"], "error_tag": "span", "wrapper_error_class": "field_with_errors", "wrapper_tag": "div", "validators": { "article[title]": { "presence": { "message": "不能为空" }, "length": { "messages": { "minimum": "过短", "maximum": "过长" }, "minimum": 2, "maximum": 100 } } } };
这段 JavaScript 使用了表单 id 作为一个全局变量的名字(本文中为 new_article),来存储这个表单的校验配置信息。下面,我先解释一下这个全局变量的属性:
- type 属性的值,为 FormBuilder 类型, 它与表单中显示、隐藏错误信息的操作有关,后面会讲到
- error_tag 和 error_class 为错误信息容器的标签和 CSS 类
- wrapper_tag 和 wrapper_error_class 为整个表单项的容器的标签和 CSS 类
- validators 是整个插件的关键,,是根据我们在 Rails 的 Model 中设置的校验规则生成的。validators 的第一层属性是各个需要校验的表单项的 name(比如 <input name="article[title]" > ),而这些属性对应的值,则表示这个表单项所需要进行的校验及校验所需的参数和出错信息。
在 client_side_validations 的源码中,把前边说的这个全局变量称为 settings,下面我为了描述方便,也这么叫它。所以在本文中我说到 settings 时请想到 window['new_article']。
二、client_side_validations 中的 validators
在说到整个插件的工作流程之前,我们先把前边说的 settings 中的 validators 属性和 client_side_validations 源码中的校验函数对应起来看一下:
var clientSideValidations = { validators: { all: function() { return jQuery.extend({}, clientSideValidations.validators.local, clientSideValidations.validators.remote) }, local: { presence: function(element, options) { /* ... */ }, acceptance: function(element, options) { /* ... */ }, format: function(element, options) { /* ... */ }, numericality: function(element, options) { /* ... */ }, length: function(element, options) { /* ... */ }, exclusion: function(element, options) { /* ... */ }, inclusion: function(element, options) { /* ... */ }, confirmation: function(element, options) { /* ... */ } }, remote: { uniqueness: function(element, options) { /* ... */ } } }, /* formBuilders、callbacks 部分代码 */ }
我把每个函数的的具体实现去掉了,这样就可以很容易的看出 settings 的 validators 所包含的,就是此处这些校验函数的名字。没错,在执行校验的时候,就是通过 settings 中的那些名字来找到这些函数并进行调用的。
三、client_side_validations 中的 formBuilders
var clientSideValidations = { /* validators 部分代码 */, formBuilders: { 'ActionView::Helpers::FormBuilder': { add: function(element, settings, message) { /* ... */ }, remove: function(element, settings) { /* ... */ } }, 'SimpleForm::FormBuilder': { add: function(element, settings, message) { /* ... */ }, remove: function(element, settings) { /* ... */ } }, 'Formtastic::FormBuilder': { add: function(element, settings, message) { /* ... */ }, remove: function(element, settings) { /* ... */ } }, 'NestedForm::Builder': { add: function(element, settings, message) { /* ... */ }, remove: function(element, settings, message) { /* ... */ } } }, /* callbacks 部分代码 */ }
在这个地方只做两件事——在页面中显示错误信息(add 函数)和去掉错误信息(remove 函数)。这几对 add、remove 函数只是在不同的 FormBuilder 下的不同实现而已。在表单项校验完毕时,根据 settings 的 type 属性来调用这里对应的 add() 或者 remove()。
四、client_side_validations 中的 callbacks
var clientSideValidations = { /* validators 和 formBuilders 部分代码 */, callbacks: { element: { after: function(element, eventData) { }, before: function(element, eventData) { }, fail: function(element, message, addError, eventData) { addError() }, pass: function(element, removeError, eventData) { removeError() } }, form: { after: function(form, eventData) { }, before: function(form, eventData) { }, fail: function(form, eventData) { }, pass: function(form, eventData) { } } } }
这个部分的代码,我没做删减,可以看出 client_side_validations 只使用了两个 callback,其余都是预留的。如果想设置 callback 可以这样做:
jQuery(function () { clientSideValidations.callbacks.element.before = function(element, eventData) { /* your code */ }; });
五、整体流程和 $.fn.validate 等主要函数
有了前面几个部分的铺垫,client_side_validations 的工作流程就好理解多了,下面我把对应的源码细节替换成注释,来大概理顺一下代码:
(function($) { $.fn.validate = function() { return this.filter('form[data-validate]').each(function() { var form = $(this); var settings = window[form.attr('id')]; // $.fn.validate() 的作用是为表单和表单项的一些事件绑定 callback // 包括前边说到的那8个 callbacks // 其中 element:validate:fail 事件触发时会调用前边提到的 formBuilders 中的 add() 函数 // 而 element:validate:pass 事件则对应调用 formBuilders 中的 remove() 函数 // 当表单的 submit 和 ajax:beforeSend 事件触发时,对此表单调用isValid(settings.validators) // 当需要校验的表单项(除radio)触发 focusout 时,对此表单项调用 isValid(参数同上) // 当需要校验的 checkbox 触发 click 时,对此表单项调用 isValid(参数同上) // 当 _confirmation 这种匹配项,触发 focusout、keyup 事件时,对此表单项调用isValid(参数同上) }); } $.fn.isValid = function(validators) { if ($(this[0]).is('form')) { return validateForm($(this[0]), validators); } else { return validateElement($(this[0]), validators[this[0].name]); } } var validateForm = function(form, validators) { // 触发 form:validate:before 事件 // 对表单中每一个需要校验的表单项调用 isValid(validators) // 触发 form:validate:pass 或 form:validate:fail 事件 // 触发 form:validate:after 事件 // 返回 true 或 false } var validateElement = function(element, validators) { // 触发 element:validate:before 事件 // 根据 validators 中的函数名字,到 clientSideValidations.validators 中找到对应的函数并调用 // 触发 element:validate:pass 或 element:validate:fail 事件 // 触发 element:validate:after 事件 // 返回 true 或 false } // Main hook // If new forms are dynamically introduced into the DOM the .validate() method // must be invoked on that form $(function() { $('form[data-validate]').validate(); }) })(jQuery);
基本就是这样了。
最后做个广告 《JavaScript语言精粹》、《基于MVC的JavaScript Web富应用开发》,这两本书对于我这种写JS都是用哪儿查哪儿,没系统学过JS的人帮助很大。
发表评论
-
RSpec笔记 - let 和 let!
2013-11-24 00:20 2069RSpec 的 let 是一个很方便的用法,但是今天在写一段测 ... -
初次在Rails项目中使用PostgreSQL,纪录一些简单的步骤
2013-11-16 10:26 1227一、安装PostgreSQL Ubuntu 下可以用 apt- ... -
[gem] acts_as_list
2013-07-09 15:09 925注意事项: 1. 当在 STI 中,用 type 字段来做 s ... -
使用 rails_admin + cancan 时,发生 No route matches {:controller=>"home"}
2013-04-12 09:32 1950囧 rails_admin 官方的 wiki 中已经写了,是我 ... -
Rails中Mongoid的时间日期字段使用 datetime_select
2013-01-23 01:57 1123http://stackoverflow.com/questi ... -
Google Maps JavaScript API V3备忘
2013-01-16 00:29 1413最近在研究Google地图相关的东西,在这里做点备忘。 1、 ... -
SimpleForm 2.0 使用方法
2012-12-06 10:43 2836从Redmine中备份出来的,有时间再重新排版 h2. Si ... -
Mongoid::Criteria 和数组
2012-10-23 12:49 1916因为 Mongoid::Criteria 的实例可以响应一些迭 ... -
使用 jQuery UI 的 Dialog 实现 Lightbox 效果
2012-10-17 14:26 0/* Custom Dialog */ .ui- ... -
平时收集的点滴知识点
2012-08-24 17:50 0大数据量 的时候 对db进行更改 需要谨慎 加字段非常慢的 ... -
Rails 开发小贴士积累
2012-08-24 14:25 860Model (ActiveRecord) 中 Boole ... -
Rails文件上传MIME类型值
2012-08-03 22:16 1000在做文件上传功能的时候,需要限制文件上传的类型,通常获取MIM ... -
Sphinx后台运行
2012-02-27 18:03 0好像直接运行/usr/local/sphinx/bin/sea ... -
Monkey Patch让Paperclip支持中文名称的文件上传
2012-02-05 14:06 1969使用Paperclip上传文件,如果文件名包含中文,会导致Ar ... -
Ubuntu下设置Sublime Text 2汉字显示
2011-12-07 10:49 7053Sublime Text 2是一款收费软件,不过目前它可以无限 ... -
Monkey Patch让Simple Form支持Bootstrap
2011-12-06 14:17 2211Twitter推出Bootstrap有段时 ... -
将Rails项目从Ruby 1.8.7升级到Ruby 1.9.2的脚本
2011-12-01 18:20 1341Ruby 1.9的代码文件中,如果包含了utf-8字符,那么需 ... -
部署Rails项目
2011-11-22 09:59 0使用Nginx部署的时候,要先通过Capistrano把项目部 ... -
Ubuntu 11.10安装RMagick
2011-11-09 21:06 1602Ubuntu 11.10(DVD)默认就安装了ImageMag ... -
使用Cucumber测试Rails时,预先装载seeds.rb中的数据
2011-10-19 22:03 1908我习惯把网站的一些预设数据放到db/seeds.rb中,比如网 ...
相关推荐
ClientSideValidations使您的Rails 5.x / Rails 6.x应用程序变得容易! 项目目标 遵循开发的客户端验证最佳实践 自动提取服务器上定义的验证规则并将其应用于客户端。 在服务器端验证规则无法在客户端上运行的情况...
本项目"rails-practice-validations"旨在提供一个实践平台,帮助开发者熟悉并掌握Rails中的验证机制。 在Rails中,验证主要通过在模型(Model)中添加相应的代码来实现。验证方法包括但不限于: 1. **存在性验证...
在client_side_validations-simple_form之前,需要simple_form和client_side_validations 。 JavaScript文件 说明取决于您的技术堆栈。 使用Webpacker时 确保您需要jQuery和客户端验证。 添加以下
在本文中,我们将深入探讨Rails3中的常用命令,帮助你更高效地进行开发工作。 首先,新建一个Rails项目是开发的起点。你可以使用以下命令创建一个新的工程: ```bash rails new 工程名 ``` 这会生成一个包含所有...
《Rails 3 in Action》是2011年由Ryan Bigg撰写的一本关于Ruby on Rails框架的权威指南,专门针对当时最新的Rails 3.1版本进行了深入解析。这本书旨在帮助开发者充分利用Rails 3.1的强大功能,提升Web应用开发的效率...
《Ruby on Rails 3 Tutorial》是一本专门为初学者设计的指南,旨在帮助读者快速掌握Ruby on Rails这一强大的Web开发框架。Ruby on Rails(简称Rails)是基于Ruby语言的一个开源框架,它采用MVC(Model-View-...
### CentOS环境下Rails 3开发环境搭建详解 #### 一、准备工作与环境配置 在开始部署Rails 3开发环境之前,我们需要确保系统上已经安装了一些基本的软件包和工具。这一步骤对于后续的Ruby和Rails安装至关重要。 ##...
《Rails 3 的方式》第二版不仅是一本技术手册,更是Rails开发者深入了解框架内部机制、提高编程技能的宝贵资源。无论是对于初学者还是有经验的开发者,这本书都能提供有价值的信息和启发,帮助他们更好地利用Rails...
Rails3 是 Ruby on Rails 框架的一个版本,它在2010年发布,引入了许多新特性并改进了框架的性能。Rake 是 Ruby 的一个构建工具,类似于 Java 的 Ant 或者 Python 的 setup.py,它允许开发者用自然语言定义任务,并...
### 关于《Beginning Rails 3》的关键知识点 #### 一、书籍概述 《Beginning Rails 3》是由Cloves Carneiro Jr. 和 Rida Al Barazi共同编写的关于使用Ruby on Rails框架进行Web开发的入门级教程。该书旨在帮助初学...
turbo-sprockets-rails3, 加速你的Rails 3资产 用于 Rails 3.2.x的涡轮链轮 通过只根据源文件的哈希来重新编译已经更改的资产,从而加快 Rails 3 rake assets:precompile的速度只编译一次以生成指纹和非打印的资产...
Ruby on Rails 3 是一个基于Ruby编程语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,极大地简化了Web开发过程。这个版本是在Ruby 1.9.2环境下发布的,带来了许多改进和新特性,旨在提高...
在“Ruby Rails 3 Linda”这一主题中,我们将会深入探讨Rails 3版本的相关知识点。 1. **安装与设置**:首先,学习如何在本地环境中安装Ruby、RubyGems和Rails。Ruby版本管理器如RVM(Ruby Version Manager)或...
标题与描述均提到了"rails3-railsconf2010",这表明内容主要聚焦于Rails 3在2010年的RailsConf会议上的关键更新与特性。Rails(Ruby on Rails)是一种用Ruby语言编写的开源全栈web应用框架,以模型-视图-控制器(MVC...
Rails3消息队列系统 Sidekiq
Ruby+on+Rails+3+Tutorial.pdf 应用Rails进行敏捷Web开发第4版.pdf (Agile Web Development with Rails) Rails.Recipes.Rails.3.Edition.pdf
### Ruby on Rails 3 教程知识点解析 #### 标题与描述中的核心知识点 - **Ruby on Rails 3**:一种流行的Web开发框架,基于Ruby语言。 - **经典教材**:表明本书是学习Ruby on Rails 3的一个权威且广受好评的资源...
The Rails™ 3 Way is the only comprehensive, authoritative guide to delivering production-quality code with Rails 3. Pioneering Rails expert Obie Fernandez and a team of leading experts illuminate ...
### Rails 3升级手册知识点详解 #### 一、Rails 3升级手册概览 本手册是一份详尽的指南,旨在帮助开发者顺利完成从旧版本Rails到Rails 3的升级过程。手册共包含近120页的内容,覆盖了升级过程中所需的所有关键信息...