您的位置:首页 > Web前端 > AngularJS

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有自带的了。用法极其简单.

<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个我之前写过一篇了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了.

<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牵连.(这个概念要懂)

好啦,基本上就是这样了,下次我才给一个完整的案例吧^^

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: