angularjs 1.3 综合学习 (one way bind , ng-if , ng-switch , ng-messages, ng-form ,ng-model )
2015-02-25 10:04
816 查看
主要讲解1.3后的一些新功能,和一些以前没有介绍的小功能(ng-if,ng-switch).
1.onewaybind
这个之前的版本已经有人自己实现了,但是在1.3之后,angularjs有自带的了。用法极其简单.
看到吗?只是把从前的{{value}}改成{{::value}}.加了::就表示这个值只是要单向绑定,之后$scope改变了也不会在同步到模板了。
2.ng-if
ng-if是用来做动态模板的,如果你的模板有一部分内容是依据某些数据来决定的就可以用啦。
他和ng-hide主要区别在,ng-if如果是false的情况它不会生成dom,这有时对性能是好的。
ng-if为true时,angularjs会使用之前clone好的模板,然后compile了append出去。
angularjs没有else指令(不过有人自己实现了),不过我们可以用上面的写法来模拟else
ng-if会自动创建新的继承scope.在有ng-model的情况下多留意,有坑.
当我们输入text的时候,$modelValue和childvalue都会更新,但是parentvalue却不会了。这是正确的原型概念(http://www.cnblogs.com/keatkeat/p/3983952.html)
一般情况我们在做form时,通常我们设计一个对象用于装所有的value,这样就不必担心继承scope引起的问题了.
稍微改一下就可以了.
ViewCode
3.ng-switch
这个和ng-if差不多,和一般jsswitch一样的概念.它也是会创建继承scope哦.
4.ng-messages
这个主要用于form验证错误时的errormessage.
注意这是一个而且的模块必须加载['ngMessages']和引入文件angular-messages.js
上面是一个能匹配多个错误信息的例子.当错误出现时,特定的div就会被显示出来了。form.email.$error是一个这样的对象:{"email":true,"minlength":true},true表示验证失败了.
5.ng-modelandng-form
这2个我之前写过一篇了http://www.cnblogs.com/keatkeat/p/3912530.html
当时还在1.3beta,现在我会把一些常用到的在讲解一篇.还有一些新新特性也一起说说。
首先要强调,如果你想把表单做好,做的很"angularway"的话,ng-form,ng-model,自定义指令,验证,都必须很清楚。你把它们连在一起才能强大。
5.1ngModel.$formatters和ngModel.$parsers
这2个东西是ng-model在同步数据的时候的pipeline,ngModel有2个主要属性($viewValue,$modelValue)
顾名思义啦,这2个值通常是一样的。但是有时候我们希望他们不一样,比如日期格式。在$modelValue是datetime,在$viewValue是string.
这时我们就可以通过拦截pipeline,做一些convertion了.
上面就是一个处理datetime的例子。
$formatters触发当model->view
$parsers触发当view->model
5.2ng-model-options
ng-model-options="{updateOn:'blur',debounce:2000}"
updateOn表示当什么event触发时写入$viewValue,debounce表示delay多久后把$viewValue同步去$modelValue
上面这个case,如果我们写入一个"keatkeat",当onblur时$viewValue马上会是"keatkeat",2秒后$modelValue会是"keatkeat".
值得注意的是:如果我们只是写了一个debounce,那么$viewValue并不会马上有"keatkeat",而是2秒后$viewValue和$modelValue同时是"keatkeat".建议不一起使用!
5.3ng-model属性方法
方法:
$render
render中文是渲染,当$modelValue被修改$digest后会同步到$viewValue(中间经过pipeline),之后angular会调用$render.
在做自定义指令时,我们就是靠注册这个方法来完成我们dom修改的。
在方法中,我们应该使用$viewValue工作,而不是$modelValue哦。
$rollbackViewValue
调用这个方法,$modeValue的值将同步到$viewModel上
一般上是配合keyupEsc和updateOn:'blur'使用
$commitViewValue
这个和$rollbackViewValue相反,是马上把$viewValue同步到$modelValue上。
属性:
$validators
顾名思义就是做验证的啦,1.3以前我们是通过pipeline来做验证的,很麻烦。
现在呢用$validators就可以了
$asyncValidators&$pending
而且还支持异步的
$pending={myValid:true}表示正在验证.
注册到$asyncValidators中的方法,我们需要返回一个promise对象就可以了.
验证如果不通过,$modelValue将会是undefined
$setViewValue
这个方法主要是用于自定义指令时,我们通过事件来更新ngmodel的值
比如inputtext,就是写一个keyupevent,当keyup触发时就会调用$setViewValue(inputValue);
这个方法会更新$viewValue,$modelValue,也会触发pipeline,validators.
注:此方法不会触发$digest(官方网站是这样写的啦)
But!我自己在1.4.5版本用好像是会的
如果value和之前一样的话,digest会触发,但是$validate不会触发
$validate()
这个方法是手动调用验证
注:此方法不会触发$digest(真的不会哦)
ng-form
有点懒,这个就不怎么介绍了。
只说重点,下次才补上吧
angular的form支持嵌套,我觉得最佳做法就是上面这个样子,最外层写一个form,内层全部用div+ng-form指令
在form里面,每一个涉及ng-model的节点,如果有附带name的话,都会直接添加进formcontrollers里面.
所以上面form.name可以访问到ngModelCtrl
form有一个$submitted属性,可以用于判断是否提交。
要reset一个form,除了把ng-model值clear完之外,还必须$setPristine()和$setUntouched();
ng-model的valid,dirty等等都会和form牵连,form也会和parentform牵连.(这个概念要懂)
好啦,基本上就是这样了,下次我才给一个完整的案例吧^^
1.onewaybind
这个之前的版本已经有人自己实现了,但是在1.3之后,angularjs有自带的了。用法极其简单.
<divng-app="app"ng-controller="ctrl"> {{::value}} </div> <scriptsrc="../../js/Stooges.js"></script> <scriptsrc="../../js/ng-1.3.10/angular.js"></script> <script> varapp=angular.module("app",[]); app.controller("ctrl",["$scope","$timeout",function($scope,$timeout){ $scope.value="keatkeat"; $timeout(function(){ $scope.value="xinyao"; },2000); }]); </script>
看到吗?只是把从前的{{value}}改成{{::value}}.加了::就表示这个值只是要单向绑定,之后$scope改变了也不会在同步到模板了。
2.ng-if
ng-if是用来做动态模板的,如果你的模板有一部分内容是依据某些数据来决定的就可以用啦。
他和ng-hide主要区别在,ng-if如果是false的情况它不会生成dom,这有时对性能是好的。
ng-if为true时,angularjs会使用之前clone好的模板,然后compile了append出去。
<divng-app="app"ng-controller="ctrl"> <divng-if="isTrue"> ok </div> <divng-if="!isTrue"> no </div> </div> <scriptsrc="../../js/Stooges.js"></script> <scriptsrc="../../js/ng-1.3.10/angular.js"></script> <script> varapp=angular.module("app",[]); app.controller("ctrl",["$scope","$timeout",function($scope,$timeout){ $scope.isTrue=false; $timeout(function(){ $scope.isTrue=true; },2000); }]); </script>
angularjs没有else指令(不过有人自己实现了),不过我们可以用上面的写法来模拟else
ng-if会自动创建新的继承scope.在有ng-model的情况下多留意,有坑.
<divng-app="app"ng-controller="ctrl"> <divng-form="form"> parentvalue:{{value}} <br/> modelvalue:{{form.age.$modelValue}} <divng-if="isTrue"> <inputtype="text"name="age"ng-model="value"/> <br/> childvalue:{{value}} </div> </div> </div> <scriptsrc="../../js/Stooges.js"></script> <scriptsrc="../../js/ng-1.3.10/angular.js"></script> <script> varapp=angular.module("app",[]); app.controller("ctrl",["$scope","$timeout",function($scope,$timeout){ $scope.isTrue=true; $scope.value="keatkeat"; }]); </script>
当我们输入text的时候,$modelValue和childvalue都会更新,但是parentvalue却不会了。这是正确的原型概念(http://www.cnblogs.com/keatkeat/p/3983952.html)
一般情况我们在做form时,通常我们设计一个对象用于装所有的value,这样就不必担心继承scope引起的问题了.
稍微改一下就可以了.
<divng-app="app"ng-controller="ctrl"> <divng-form="form"> parentvalue:{{value.age}} <br/> modelvalue:{{form.age.$modelValue}} <divng-if="isTrue"> <inputtype="text"name="age"ng-model="value.age"/> <br/> childvalue:{{value.age}} </div> </div> </div> <scriptsrc="../../js/Stooges.js"></script> <scriptsrc="../../js/ng-1.3.10/angular.js"></script> <script> varapp=angular.module("app",[]); app.controller("ctrl",["$scope","$timeout",function($scope,$timeout){ $scope.isTrue=true; $scope.value={age:13};//换成对象 }]); </script>
ViewCode
3.ng-switch
这个和ng-if差不多,和一般jsswitch一样的概念.它也是会创建继承scope哦.
<divng-app="app"ng-controller="ctrl"> <divng-switch="switchCase"> <divng-switch-when="case1">case2</div><!--case1必须是一个string,不可以是表达式,(case1!=$scope.case1)--> <divng-switch-when="case2">case2</div> <divng-switch-default>defaultcase</div> </div> </div> <scriptsrc="../../js/Stooges.js"></script> <scriptsrc="../../js/ng-1.3.10/angular.js"></script> <script> varapp=angular.module("app",[]); app.controller("ctrl",["$scope","$timeout",function($scope,$timeout){ $scope.switchCase="case2"; $timeout(function(){ $scope.switchCase="case1"; },2000); }]); </script>
4.ng-messages
这个主要用于form验证错误时的errormessage.
<divng-app="app"ng-controller="ctrl"> <formnovalidate> <divng-form="form"> <inputtype="email"ng-minlength="2"requiredname="email"ng-model="formData.email"/> <divng-messages="form.email.$error"ng-messages-multiple> <divng-message="required">mustfillinemail</div> <divng-message="email">noaemailformat</div> <divng-message="minlength">atleast2words</div> </div> </div> </form> </div> <scriptsrc="../../js/Stooges.js"></script> <scriptsrc="../../js/ng-1.3.10/angular.js"></script> <scriptsrc="../../js/ng-1.3.10/angular-messages.js"></script> <script> varapp=angular.module("app",['ngMessages']); app.controller("ctrl",["$scope","$timeout",function($scope,$timeout){ $scope.formData={}; }]); </script>
注意这是一个而且的模块必须加载['ngMessages']和引入文件angular-messages.js
上面是一个能匹配多个错误信息的例子.当错误出现时,特定的div就会被显示出来了。form.email.$error是一个这样的对象:{"email":true,"minlength":true},true表示验证失败了.
5.ng-modelandng-form
这2个我之前写过一篇了
当时还在1.3beta,现在我会把一些常用到的在讲解一篇.还有一些新新特性也一起说说。
首先要强调,如果你想把表单做好,做的很"angularway"的话,ng-form,ng-model,自定义指令,验证,都必须很清楚。你把它们连在一起才能强大。
5.1ngModel.$formatters和ngModel.$parsers
这2个东西是ng-model在同步数据的时候的pipeline,ngModel有2个主要属性($viewValue,$modelValue)
顾名思义啦,这2个值通常是一样的。但是有时候我们希望他们不一样,比如日期格式。在$modelValue是datetime,在$viewValue是string.
这时我们就可以通过拦截pipeline,做一些convertion了.
<divng-app="app"ng-controller="ctrl"> <formnovalidateautocomplete="off"> <divng-form="form"> modelvalue:{{form.name.$modelValue}},Type:{{getType(form.name.$modelValue)}}<br/> viewvalue:{{form.name.$viewValue}},Type:{{getType(form.name.$viewValue)}}<br/> <inputtype="text"name="name"ng-model="formData.name"my-datetime-convert/><br/> </div> </form> </div> <scriptsrc="../../js/ng-1.3.10/angular.js"></script> <script> varapp=angular.module("app",[]); app.directive("myDatetimeConvert",[function(){ return{ restrict:"A", require:"ngModel", link:function(scope,elem,attrs,ngModel){ ngModel.$formatters.push(function(value){ returnvalue.toDateString();//把datetime各式转换成string格式. }); ngModel.$parsers.push(function(value){ try{ returnnewDate(value); }catch(e){ returnundefined; } }); } } }]); app.controller("ctrl",["$scope","$timeout",function($scope,$timeout){ $scope.formData={ name:newDate() }; $scope.getType=function(value){ returnObject.prototype.toString.call(value).slice(8,-1).toLowerCase(); } }]); </script>
上面就是一个处理datetime的例子。
$formatters触发当model->view
$parsers触发当view->model
5.2ng-model-options
ng-model-options="{updateOn:'blur',debounce:2000}"
updateOn表示当什么event触发时写入$viewValue,debounce表示delay多久后把$viewValue同步去$modelValue
上面这个case,如果我们写入一个"keatkeat",当onblur时$viewValue马上会是"keatkeat",2秒后$modelValue会是"keatkeat".
值得注意的是:如果我们只是写了一个debounce,那么$viewValue并不会马上有"keatkeat",而是2秒后$viewValue和$modelValue同时是"keatkeat".建议不一起使用!
5.3ng-model属性方法
方法:
$render
render中文是渲染,当$modelValue被修改$digest后会同步到$viewValue(中间经过pipeline),之后angular会调用$render.
在做自定义指令时,我们就是靠注册这个方法来完成我们dom修改的。
在方法中,我们应该使用$viewValue工作,而不是$modelValue哦。
$rollbackViewValue
调用这个方法,$modeValue的值将同步到$viewModel上
<inputtype="text"name="name"ng-model="formData.name"ng-model-options="{updateOn:'blur'}"ng-keyup="keyup($event,form.name)"/> $scope.keyup=function(event,ngModel){ if(event.keyCode==27){ ngModel.$rollbackViewValue(); } }
一般上是配合keyupEsc和updateOn:'blur'使用
$commitViewValue
这个和$rollbackViewValue相反,是马上把$viewValue同步到$modelValue上。
属性:
$validators
顾名思义就是做验证的啦,1.3以前我们是通过pipeline来做验证的,很麻烦。
现在呢用$validators就可以了
<divng-app="app"ng-controller="ctrl"> <formnovalidateautocomplete="off"> <divng-form="form"> modelvalue:{{form.name.$modelValue}}<br/> viewvalue:{{form.name.$viewValue}}<br/> error:{{form.name.$error|json}} <inputtype="text"name="name"ng-model="formData.name"ng-model-options="{debounce:2000}"my-valid/> <br/> </div> </form> </div> <scriptsrc="../../js/Stooges.js"></script> <scriptsrc="../../js/ng-1.3.10/angular.js"></script> <script> varapp=angular.module("app",[]); app.directive("myValid",[function(){ return{ restrict:"A", require:"ngModel", link:function(scope,elem,attrCollection,ngModel){ ngModel.$validators["myValid"]=function(modelValue,viewValue){ returnmodelValue=="kknd"; } } } }]); app.controller("ctrl",["$scope","$timeout",function($scope,$timeout){ $scope.formData={name:"kknd"}; }]); </script>
$asyncValidators&$pending
而且还支持异步的
<divng-app="app"ng-controller="ctrl"> <formnovalidateautocomplete="off"> <divng-form="form"> modelvalue:{{form.name.$modelValue}}<br/> viewvalue:{{form.name.$viewValue}}<br/> error:{{form.name.$error|json}}<br/> pending:{{form.name.$pending}} <inputtype="text"name="name"ng-model="formData.name"ng-model-options="{debounce:1000}"my-valid/> <br/> </div> </form> </div> <scriptsrc="../../js/Stooges.js"></script> <scriptsrc="../../js/ng-1.3.10/angular.js"></script> <script> varapp=angular.module("app",[]); app.directive("myValid",["$q",function($q){ return{ restrict:"A", require:"ngModel", link:function(scope,elem,attrCollection,ngModel){ ngModel.$asyncValidators["myValid"]=function(modelValue,viewValue){ vardefer=$q.defer(); log("asyncvalidsend"); setTimeout(function(){ log("asyncvalidback"); if(modelValue=="kknd"){ defer.resolve(true); } else{ defer.reject(false); } },3000); returndefer.promise; } } } }]); app.controller("ctrl",["$scope","$timeout",function($scope,$timeout){ $scope.formData={name:"kknd33"}; }]); </script>
$pending={myValid:true}表示正在验证.
注册到$asyncValidators中的方法,我们需要返回一个promise对象就可以了.
验证如果不通过,$modelValue将会是undefined
$setViewValue
这个方法主要是用于自定义指令时,我们通过事件来更新ngmodel的值
比如inputtext,就是写一个keyupevent,当keyup触发时就会调用$setViewValue(inputValue);
这个方法会更新$viewValue,$modelValue,也会触发pipeline,validators.
注:此方法不会触发$digest(官方网站是这样写的啦)
But!我自己在1.4.5版本用好像是会的
如果value和之前一样的话,digest会触发,但是$validate不会触发
$validate()
这个方法是手动调用验证
注:此方法不会触发$digest(真的不会哦)
ng-form
有点懒,这个就不怎么介绍了。
只说重点,下次才补上吧
<formnovalidateautocomplete="off"> <divng-form="form"> modelvalue:{{form.name.$modelValue}}<br/> viewvalue:{{form.name.$viewValue}}<br/> error:{{form.name.$error|json}}<br/> pending:{{form.name.$pending}} <inputtype="text"name="name"ng-model="formData.name"ng-model-options="{debounce:1000}"my-valid/> <divng-click="click(form.name)">ok</div> <br/> </div> </form>
angular的form支持嵌套,我觉得最佳做法就是上面这个样子,最外层写一个form,内层全部用div+ng-form指令
在form里面,每一个涉及ng-model的节点,如果有附带name的话,都会直接添加进formcontrollers里面.
所以上面form.name可以访问到ngModelCtrl
form有一个$submitted属性,可以用于判断是否提交。
要reset一个form,除了把ng-model值clear完之外,还必须$setPristine()和$setUntouched();
ng-model的valid,dirty等等都会和form牵连,form也会和parentform牵连.(这个概念要懂)
好啦,基本上就是这样了,下次我才给一个完整的案例吧^^
相关文章推荐
- AngularJS的学习--ng-show/ng-hide/ng-if和ng-switch
- AngularJS学习之ng-if嵌套ng-model变量冲突解决
- AngularJS的学习--ng-show/ng-hide/ng-if和ng-switch
- angularjs学习 ng-Messages表单验证
- [AngularJS] Angular 1.3: ng-model-options updateOn, debounce
- AngularJs-ng-app -ng-model-ng-bind指令讲解和使用
- AngularJs中模块的依赖注入,ng-model、ng-bind和{{}}的区别,路由机制。
- AngularJS中ng-if/ng-switch时找不到scope下的定义的变量
- angularjs,ng-if导致input中ng-model双向绑定
- AngularJS 关于ng-model和ng-bind还有{{}}
- AngularJS 关于ng-model和ng-bind还有{{}}
- [AngularJS] Angular 1.3 ngMessages with ngAnimate
- AngularJs 中的ng-if ng-swith ng-bind-template
- AngularJS – Conditional Display using ng-show / ng-hide, ng-if, ng-include, ng-switch
- ng-model,ng-value,ng-bind,{{}}----angularJS数据绑定
- AngularJS解决ng-if中的ng-model值无效的问题
- angular2中standalone=“true”和Name attribute must be set if ngModel is used within a form的问题
- Angular 学习系列 - - form.FormController、ngModel.NgModelController
- angularjs之ng-if、ng-show、ng-switch那些事
- angularjs中ng-bind和ng-model用法