angularJs中ngModel的坑
angular中指令被用的最多的除了ng-repeat之外就非他莫属了吧,由于各种业务的需求,我们经常需要去写一些继承ngModel的指令,来满足各种奇葩需求,最多的莫过于表单的验证啦,另外你在封装一些jquery插件的时候,也是需要继承ngModel的,最典型的莫过于 datepicker、fileUpload等等。
但是ngModel本身其实有很多坑,在这里分享给大家,如果大家又遇到其他问题,欢迎补充:
首先我们要知道一些概念的东西,这里我就不占篇幅了,不了解的可以先去看看这篇文章:
http://www.cnblogs.com/liulangmao/p/4110137.html
在这里,我基本分为两种问题,一种是viewValue和modelValue不同的问题,另一种是管道问题
第一种:viewValue和modelValue不同的问题
1.viewValue想变成modelValue
2.modelValue想变成ViewValue
3.moduleValue想和viewModel不一样
4.viewModel和DOM元素的值不一样
要想解决这些问题,我们先来了解一些$apply的一个问题,那就是执行$apply之后数据是以什么为主的
①viewValue -> modelValue
②modelValue -> viewValue,于是我们写了下面这个指令
<input type="text" ng-model="vm.modelTest" model-test>
.directive('modelTest',function(){
return {
require : 'ngModel',
link : function(scope,iElm,iAttrs,ngModelCtrl){
iElm.on('mouseenter',function(){
console.info("打印出更改之后,没有执行$apply的值")
console.log(ngModelCtrl); //更改modelValue的值
ngModelCtrl.$modelValue = "test change"; console.info("打印出更改之后,没有执行$apply的值")
console.log(ngModelCtrl); //执行$apply
scope.$apply(); console.info("打印出更改之后,执行$apply的值")
console.log(ngModelCtrl);
})
}
}
})
从上面的指令,我们不难得出一个比较武断的结论 $apply会根据viewValue的值而改变modelValue的值,也就是modelValue -> viewValue,那么,我们可以开始解决我们的问题了。
1.viewValue想变成modelValue
这种情况很少, 但是如果你在jq的操作就可能发生这种需求,一般依然还是$apply让model的值重新更新,使用了$apply就会触发$render()函数,因为modelValue的变化,会导致$render触发
2.modelValue想变成ViewValue (看了上面的实验,我想你应该懂了,直接使用$apply)
3.moduleValue想和viewModel不一样
一般情况都会使用管道去解决,但是有个其他思路可以提供给大家,下面这段代码是在国外看到的,觉得挺不错的,效果大家可以去尝试下,将model的值变成数组。
ngModelCtrl.$viewChangeListeners.push(function(){
$parse(iAttrs.ngModel).assign(scope, ngModelCtrl.$viewValue.split(','));
});
第二种:管道问题
管道是什么呢,在ngModel里面其实就是view视图和model视图数据交互的时候需要经过的数组或对象,这个数组或对象由方法组成,每次经过都会执行数组里面的方法,并返回结果。一共有四种管道
$formatters :它是model视图转向view视图的管道(数组),model的值会经过他才转变成view视图的值,另外它的调用顺序是最特别的,从后往前调用,,越在数组后面,越早调用。
$parsers : 它正好是跟$formatters相反,是view视图转向model视图的管道(数组),view的值会经过他才转变成model视图的值,在1.2.x(兼容IE8)之前一般我们会在这里实现或扩展验证功能
$validators:这是在1.3.x之后出现的管道(json对象),来帮助我们实现和扩展验证功能的,当我们进入$parsers的同时,同时也会进入$validators,在这里我贴段源码(验证required)给大家看看,我想大家应该能理解这个管道的功能
ctrl.$validators.required = function(modelValue, viewValue) {
return !attr.required || !ctrl.$isEmpty(viewValue);
};
$asyncValidators :功能与$validators相似,不同的是他可以实现异步验证,你可以在管道内部执行异步处理,会在结果返回之后,才去设置验证结果,这是个大课题,我看到有人讨论过,我也就不详细讲了http://www.cnblogs.com/liulangmao/p/4118868.html可以进去这个博客看看。
好了,ngModel的一些东西基本已将讲完了,另外还有一些就不仔细去说了,我的博客里面还有一篇关于$render的详解,有兴趣的可以了解下。
此帖是原创,转载请注明
angularJs中ngModel的坑的更多相关文章
- AngularJs 中ngModel绑定HTML5 date数据同步问题
以下代码例子中,直接将date类型的input标签与ng-model对应的变量绑定,会出现内存数据和页面数据不一致的问题.虽然AngularJS是双向数据绑定,但是如果用下面的方法,在页面更新date ...
- AngularJS 中ng-model通过$watch动态取值
这个例子的意思是,当xxxx的长度不超过6时,xxxx和yyyy两个input的model是无关的,但当xxxx超过6,则yyyy会跟随其值而变化. 另一种做法是在input的ng-model后面添加 ...
- AngularJS移动开发中的各种坑
捂脸,辛酸泪ing...... 本文主要涉及部分在移动设备上特有的问题. 相对来说,Jquery侧重DOM操作,AngularJS是以视图模型和双向绑定为核心的. DOM操作的问题 避免使用 jQue ...
- AngularJS 中的作用域
问题引入 使用 Angular 进行过一段时间的开发后,基本上都会遇到一个这样的坑: 123456789101112 <div ng-controller="TestCtrl" ...
- 深入学习AngularJS中数据的双向绑定机制
来自:http://www.jb51.net/article/80454.htm Angular JS (Angular.JS) 是一组用来开发Web页面的框架.模板以及数据绑定和丰富UI组件.它支持 ...
- AngularJS中的表单验证
AngularJS中的表单验证 AngularJS自带了很多验证,什么必填,最大长度,最小长度...,这里记录几个有用的正则式验证 1.使用angularjs的表单验证 正则式验证 只需要配置一个正则 ...
- angularjs中的directive scope配置
angularjs中的directive scope配置 定义directive其中重要的一环就是定义scope,scope有三种形式: 默认的scope,DOM元素上原有的scope scope: ...
- AngularJS中的指令全面解析(转载)
说到AngularJS,我们首先想到的大概也就是双向数据绑定和指令系统了,这两者也是AngularJS中最为吸引人的地方.双向数据绑定呢,感觉没什么好说的,那么今天我们就来简单的讨论下AngularJ ...
- angularJS中directive与controller之间的通信
当我们在angularJS中自定义了directive之后需要和controller进行通讯的时候,是怎么样进行通讯呢? 这里介绍3种angular自定义directive与controller通信的 ...
随机推荐
- VS2010 制作安装包,无法生成卸载快捷方式
目前我出现了这个错误,原因是项目目录中包含了中文字符导致的,我改变了文件夹之后,就没问题了
- POJ 1258 Agri-Net(Prim)
( ̄▽ ̄)" #include<iostream> #include<cstdio> #include<cmath> #include<algori ...
- 我的 Github 个人博客是怎样炼成的
Joey's Blog 长大后才发现政府建造 GFW 真是太 TM 机智了,由于本人自制力较差,且不说 91porn, youporn 等两性知识网站的超强战斗力,单单一个Youtube就可以让我瞬间 ...
- android studio导入包后无法import
android studio导入jar包的方法: 1.将jar包放到module的libs目录下 2.在所导入的jar包上右键,选择“Add as library”. 其中,第二点跟eclipse不同 ...
- Qt 5简介
Qt 5简介 Qt 5概要介绍 在Qt 5这个版本中,Qt Quick成为了Qt的核心.但是Qt 5也继续提供了本地C++强大的功能来完成更好的用户体验,也提供了对OpenGL/OpenGL ES图形 ...
- NSTimer定时器
NSTimer的避免内存泄露与控制器的正确引用和释放:
- # 泰语字符串字符分割 --- UTF-8编码格式
1.泰语编码格式 泰语用的编码格式是:ISO 8859-11,这个是Latin编码系列,是从"ISO-8859-1"发展过来的,采用的是8bit一个字,所以泰语中的英文字母或者数字 ...
- Local declaration of 'XXX' hides instance variable
今天调试程序遇到这么一个警告! Local declaration of 'XXX' hides instance variable 遇到这种原因,是因为本地变量跟函数参数变量同名.改变其一即可.
- java基础增强
Eclipse使用: java Compile配置的是java编译环境 java Build path配置的是java运行环境 运行环境的版本必须高于编译环境的版本.否则报错 工程上 右键--prop ...
- Python 3.5.1 Syntax & APIs(Continue Updating..
print(x, end=' ') instead of print(x) to escape the default line-changing-output. print(str.ljust(si ...