目录
- 前言
- 实现思路
- 初始化
- 监听变化
- 在线预览
- 参考
前言
本文章思想来自https://github.com/rubentd/dirrty
为了更好理解脏值检查(dirty checking),本文将用一个非常简单但实用的例子来阐述脏检查的实际应用,也为理解AngularJS的脏值检测或双向绑定做铺垫。
从需求出发去理解
有一个form表单,初始化时或者未发生任何改变时,不允许提交即禁用按钮。当有元素的初始值(或默认值)发生改变时,允许提交。这是一个脏值检查经典案例,如果有字段被修改时就可以理解为该表单变“脏”了。
实现思路
初始化
表单是否变“脏”,最好的方法是通过对比元素的前后值是否发生改变进行判断,所以在表单初始化时,遍历每一个表单元素(node
)并添加一个属性以存储他们的初始值node.value
,这个属性我们可以自定义为data-dirrty-initial-value
值得注意的是,表单元素中input
的checkbox
和radio
没有初始值node.value
而应该判断是否被选中node.checked
,
if(node.getAttribute('type') === 'checkbox'||node.getAttribute('type') === 'radio'){
node.setAttribute('data-dirrty-initial-value',node.checked)
}else {
node.setAttribute('data-dirrty-initial-value',node.value)
}
监听变化
因为表单中每一个元素的值都是独立的,所以检测form表单是否变“脏”,需要从单一元素出发判断是否变“脏”,再全部反馈给form:当存在一个元素变“脏”,则表单视为变“脏”。所以监听元素变“脏”时,添加一个属性data-is-dirrty=true
以存储这个反馈。
表单事件监听用addEventListener('input',event)
,并使用事件代理。
form.addEventListener('input',function(e){
let _value;
if(e.target.getAttribute('type') === 'checkbox'||e.target.getAttribute('type') === 'radio'){
_value = e.target.checked+''
}else {
_value = e.target.value+''
}
e.target.setAttribute('data-is-dirrty',_value!==e.target.getAttribute('data-dirrty-initial-value'))
})
在线预览
https://1uokun.github.io/h5/dist/components/dirty-checking.html
案例非常简单,但对AngularJS双向绑定的理解基础非常重要,下一篇将基于这个思想解析AngularJS双向绑定
参考
- [1] https://github.com/rubentd/dirrty
github
网友评论