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通信的 ...
随机推荐
- ios UIApplication简单使用
每个app有且只有一个UIApplication对象,当程序启动的时候通过调用UIApplicationMain方法得到的.可以通过sharedApplication方法得到. UIApplicati ...
- C语言_愤怒的小鸟
// ConsoleApplication4.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<stdio.h> ...
- VBS 自动发送邮件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- DB9_公头_母头_串口引脚定义及RS-232串口线制作方法
RS-232连接线制作方法 材料及工具 一根双绞线(8芯).一个标准RJ45头.一个DB9孔型插头.一把RJ45专用工具.一个电烙铁及若干焊锡. 引脚定义 按以下管脚定义制作RJ45端头:I表示网络视 ...
- Http Post与Get等
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP ...
- webstrom管理git
先写一段 webstrom文件名变色:1.绿色的文件添加 2.蓝色的原有文件修改 如果出现““No such file or directory”或类似的语句,说明缺少ssh的key.那么我们就得创建 ...
- perl的package和module
来源: http://www.cnblogs.com/itech/archive/2010/03/23/1692836.html 一 package 1) package 相当于C++中的namesp ...
- CentOS6.6 搭建Zabbix_3.0
公司有下发内网监控服务器的需求 使用zabbix监控 所以这篇文章是讲述的zabbix的搭建 其实网上很多地方都有 可以参考 环境安装 系统环境: # cat /etc/redhat-release ...
- b端商家赋值权限
- Win32 SDK Combo Box
如下图所示,显示了三种不同风格的Combo Box样式.当然,现在这样看不出第一种与第三种之间的区别,但是第二种与其他两种的区别是明显的,第二种的列表框始终是出于现实状态的. Combo Box: 一 ...