1. $eval 方法对绑定的属性值直接进行解析
$scope.expr2 = '20 + 1 | number:0';
2. ng-repeat
指令复制元素-在复制过程中可以添加元素相应的属性-专有变量
$first
$last
$middle
$index
{ {$first?'yes':'no"}}
3. 添加元素样式
$scope.red = "red";
字符串数组形式添加样式
$scope.blnfocus = false;
定义key/value对象的方式添加多个css样式
$scope.a = false;$scope.b = true;
4. 控制元素显示,隐藏状态
页面中调用ng-show,ng-hide,ng-switch指令绑定$scope对象的属性值
ng-switch 指令中 on可有可无,当on于多个或某个ng-switch-when指令的元素匹配时,这些元素显示,如果没有匹配的ng-switch-default显示.
divhide
- taoguorong
- more
5. 表单基本验证功能
$pristine:表单或控件内容是否未输入过
$dirty:表单或控件内容是否已输入过
$valid:表单或控件内容是否已验证通过
$invalid:表单或空间内容是否未验证通过
$error:表单或控件验证时的错误提示信息
6. 表单中的checkbox控件和redio控件
通过ng-model绑定控制器的属性,一旦绑定完成,首次加载时,将以绑定的值作为控件的初始化状态.
ng-true-value表示选中后返回的值,后者表示没有被选中时返回的值,redio只有被选中的会返回其被选中的值.
7. 表单中的select控件
可以借助ng-option指令属性,将数组,对象类型的数据添加到<option>元素中,同时还能在添加数据时进行分组显示.
绑定简单的数据类型:
通过ng-option指令属性值,采用...for...in...格式将数组与<select>控件绑定
绑定简单的对象数据
通过ng-option指令属性值,采用...as...for...in...格式将对象与<select>控件绑定,as前面部分对应元素的value值,用于选中时获取,as后面部分对应元素的text值,用于直接显示
以分组的形式绑定对象数据
通过ng-option指令属性值,采用...as...group by for..in...
8.过滤器
过滤器的主要功能是格式化数据,这里所说的数据包括视图模板中的表达式,也包括控制器中的数组和对象.
过滤器的三种调用方式:
1.单个过滤器
{
{}}双括号为表达式标记,在括号中 | 为管道符,通过该符号分为前后两部分,前部分为表达式,后部分为过滤器名称
{ { 8.8 | number:1 | currency}}
number过滤器要放在currency过滤器前边,原因大家懂得
2.多个过滤器
{
{表达式 | 过滤器1 | 过滤器2 | ...}}3.带参数的过滤器
{
{表达式 | 过滤器1 :参数1 : 参数2}}currency:货币过滤器
number:四舍五入小数点个数过滤器排序方式过滤:
$scope.data = [ {name:"张晓明",sex:"男",age:"24",score:95} ]
匹配方式过滤:
{
{数据 | filter:'匹配字符'}},一旦添加该参数,将在整个数据的属性中查找匹配项,找到后则显示,找不到则不显示,字符内容必须加引号{
{data | filter:80}},在data数据的各个属性中查找包含"80"内容的记录在字符参数中使用对象形式匹配指定属性的数据:
如果在过滤数据时已经确定了数据匹配的属性范围,可以在字符参数中通过对象的形式指定匹配的属性名称,如下
{
{数据 | filter:对象}}上述调用格式的对象中,过滤器参数是一个对象,这个对象通过key/value方式声明属性名称和匹配的字符内容,如果属性名称为$,则表示在全部的属性中查找,如下
{
{data | filter:{score:80}}} { {data | filter:{$:80}}}后者相当于{
{data | filter:80}}在字符参数中使用自定义函数匹配相应数据:
{
{数据 | filter:函数名称}}参数默认传递循环过程中的当前元素
var con = angular.module('main',[]); con.controller('testController',['$scope',function($scope){ $scope.a_data=[ {id:"1001",name:"小学"}, {id:"1002",name:"初中"}, {id:"1003",name:"大学"} ]; $scope.b_data=[ {id:"1001",name:"(1)班",grade:"一年级"}, {id:"1002",name:"(2)班",grade:"二年级"}, {id:"2001",name:"(1)班",grade:"一年级"}, {id:"2002",name:"(2)班",grade:"二年级"}, {id:"3001",name:"(1)班",grade:"一年级"}, {id:"3002",name:"(2)班",grade:"二年级"} ]; $scope.data = [ {name:"张晓明",sex:"男",age:"24",score:95}, {name:"李晓东",sex:"女",age:"25",score:80}, {name:"马晓华",sex:"男",age:"30",score:85}, {name:"师小婕",sex:"女",age:"23",score:100} ]; $scope.findscore = function (e){ return e.score >80 && e.score < 100; }
- 序号 姓名 性别 年龄 分数
- { {$index + 1}} { {stu.name}} { {stu.sex}} { {stu.age}} { {stu.score}}
自定义过滤器:
在页面模块中注册一个过滤器的构造方法,改方法将返回一个以输入值为首个参数的函数,在函数体中实现过滤器功能.而输入值为默认的被传入过滤器的对象.
- 序号 姓名 性别 年龄 分数
- { {$index + 1}} { {stu.name}} { {stu.sex}} { {stu.age}} { {stu.score}}
过滤器默认传入参数e,代表当前元素.在自定义过滤器中,当前元素代表整个集合对象,在自定义函数过滤器中当前元素为整个结合对象中的当前循环元素.
返回以输入值(被过滤值)为首个参数的函数,通过return返回一个函数,参数e为在调用过滤器时,会被过滤的数据自动注入的,其他参数为过滤器传入的自定义参数,通过冒号向过滤器传递,先定义返回值,在做逻辑处理.
表头排序:
- 序号 姓名 性别 年龄 分数
- { {$index + 1}} { {stu.name}} { {stu.sex}} { {stu.age}} { {stu.score}}
确定controller作用域后,controller为变量初始化,这个时候变量已经被赋值,函数变量会被初始化,但是不会执行函数.
orderBy过滤器带有两个参数,第一个参数指定排序的属性名,第二个参数指定排序的方向,该值默认或缺省时为升序,1为降序,0为升序.
字符查找:
name引号可有可无.
9.作用域:
作用域能存储数据模型,为表达式提供上下文环境和监听表达式变化并传播事件,它是页面视图和控制器之间的重要桥梁.
提供了$watch方法来监听数据模型的变化,ng-model实现双向数据绑定就是通过该方法进行数据模型的监听.
提供了$apply方法为各种类型的数据模型改变提供支撑,例如通过视图模板中的ng-click来执行控制器中的代码.
提供了执行环境,一个表达式必须在拥有该表达式属性的作用域中执行,作用域通过提供$scope对象,使所有的表达式对象都拥有执行环境.
$watch:
$scope.count = 0; $scope.name = ''; $scope.$watch('name',function(){ $scope.count ++; })累计变化次数:{ {count}}
需要注意的是第一次加载时初始化过程中也是认为该值是改变的undefined--初始化,该方法也会执行.
作为数据模型的作用域:
作用域是控制器和视图的桥梁,同时作用域也是指令和视图的桥梁,无论是指令,还是控制器他们都可以通过作用域与视图中的DOM进行绑定.两条数据关系链
指令->作用域->视图 控制器->作用域->视图
作用域的层级和事件:
子级作用域可以继承父级作用域中的全部属性和方法,同级别子作用域不可以相互访问各自的属性和方法.
引入作用域
con.controller('testController',['$scope',function($scope){
作用域事件传播:
两种方式可以实现作用域间的通信
服务(service):
事件(event):
Angular中提供的两个方法:$broadcasted,$emitted
$broadcasted:将事件从父级作用域传播到子级作用域
$broadcasted(eventname,data) data为事件传播过程中携带的数据信息.
$emitted:将事件从子级作用域传播到父级作用域
$emitted(eventname,data)
除了这两个传播事件的方法外,还需要调用$on方法,在作用域中监控传播来的事件,并获取相应的数据.$on(eventname,function(event,data){接收传播事件的处理方法})
在一个作用域中定义事件的传播,然后在其他作用域中通过$on方法监控事件传播的状态.
不同controller的作用域不同,通过调用作用域中的函数,并定义事件的传播,在其他的作用域中监听事件传播.controller1 $scope.to_patient = function(){ $scope.$emit('event_1',"事件来源于子级") } $scope.to_child = function(){ $scope.$broadcast('event_2',"事件来源于父级") }controller2 $scope.$on('event_1',function(event,data){ ... })
在监听函数中通过event下边相关方法操作被监听的域中的相关操作
10.依赖注入:
依赖注入原理:
var myApp = angular.module('myapp',[]); myApp.controller('ctl',['$scope',function($scope){ }])myApp.config(function($controllerProvider){ $controllerProvider.register('ctl',['$scope'.Function($scope){ }]) })
第一段代码为常用代码,第一段代码在Angular中执行的本质其实是第二段代码.
11.angular中mvc模式:
模板跳转:
12. Angular 的服务
在Angular中服务是一种单利对象,服务的主要功能是为实现应用的功能提供数据和对象.按照功能不同,分为内置和自定义的服务.
内置服务如:$scope,$http,$windows,$location
$location:
获取当前地址栏中完整的url地址.
myApp.controller('ctl1',function($scope,$location){ $scope.clicked = function(){ $scope.url = $location.absUrl(); } })
自定义服务:
只需将服务注入到需要服务的容器中(控制器,指令,或其他自定义服务)就可以采用对象的方式调用服务中的属性和方法
定义服务的方法主要包含两种,一种是使用内置的$provider服务,一种是调用模块中的服务注册方法,如factory,service,constant,value等方法
添加自定义服务依赖选项方法:
隐式声明:指的是在创建服务的函数中,直接在参数中调用,不进行任何声明,如果对代码进行压缩时,注入的对象可能失效
app.factory('serviceName',function(dep1,dep2){});
调用$inject属性:将需要注入服务的各种对象包装成一个数组,并将它们作为$inject属性值,但是执行效率很低,不推荐
sf表示服务执行的函数
var sf = functioin(dep1,dep2){};sf.$inject = ['dep1','dep2'];app.factory('ServiceName',sf);
显示声明:指的是在创建服务的函数中,添加一个数组,在数组中顺序声明需要注入的服务或对象名称,高效,不丢代码,推荐使用,参数中的名称和声明可以不一样但是顺序必须一样
app.factory('serviceName',['dep1','dep2',function(dep1,dep2){}]);
&& 通过指令在ng-repeat中动态添加删除class
13. $apply Scope提供$apply方法传播Model的变化
什么时候使用$apply()方法呢?情况非常少,实际上几乎我们所有的代码都包在scope.apply()里面,像ng−click,controller的初始化,http的回调函数等。在这些情况下,我们不需要自己调用,实际上我们也不能自己调用,否则在apply()方法里面再调用apply()方法会抛出错误。如果我们需要在一个新的执行序列中运行代码时才真正需要用到它,而且当且仅当这个新的执行序列不是被angular JS的库的方法创建的,这个时候我们需要将代码用scope.apply()包起来。下面用一个例子解释:{ {message}}functionCtrl($scope) { $scope.message ="Waiting 2000ms for update"; setTimeout(function () { $scope.message ="Timeout called!"; // AngularJS unaware of update to $scope }, 2000);} 上面的代码执行后页面上会显示:Waiting 2000ms for update。显然数据的更新没有被angular JS觉察到。 接下来,我们将Javascript的代码稍作修改,用scope.apply()包起来。functionCtrl($scope) { $scope.message ="Waiting 2000ms for update"; setTimeout(function () { $scope.$apply(function () { $scope.message ="Timeout called!"; }); }, 2000);} 这次与之前不同的是,页面上先会显示:Waiting 2000ms for update,等待2秒后内容会被更改为:Timeout called! 。显然数据的更新被angular JS觉察到了。 NOTE:我们不应该这样做,而是用angular JS提供的timeout方法,这样它就会被自动用apply方法包起来了。科学是把双刃剑 最后,我们再来瞅一眼scope.apply()和scope.apply(function)方法吧!虽然angular JS为我们做了很多事情,但是我们也因此丢失了一些机会。从下面的伪代码一看便知:function$apply(expr) { try { return$eval(expr); } catch(e) { $exceptionHandler(e); } finally { $root.$digest(); }} 它会捕获所有的异常并且不会再抛出来,最后都会调用$digest()方法。总结一下 $apply()方法可以在angular框架之外执行angular JS的表达式,例如:DOM事件、setTimeout、XHR或其他第三方的库。这仅仅是个开始,水还有很深,欢迎大家一起来deep dive!
14.scope.$watch
$watch(watchFn,watchAction,deepWatch)
watchFn:angular表达式或函数的字符串
watchAction(newValue,oldValue,scope):watchFn发生变化会被调用
deepWatch:可选的布尔值命令检查被监控的对象的每个属性是否发生变化
$watch会返回一个函数,想要注销这个watch可以使用函数
scope.$watch( function () { return scope.$eval(attrs.bfAssertSameAs); }, function () { ngModel.$setValidity('same', isSame(ngModel.$modelValue)); } );
var firstController = function ($scope){ $scope.name='张三'; $scope.count=0; // 监听一个model 当一个model每次改变时 都会触发第2个函数 $scope.$watch('name',function(newValue,oldValue){ ++$scope.count; if($scope.count > 30){ $scope.name = '已经大于30次了'; } }); }
15.通过指令获取元素的值,以及作用域中的其他值
16.页面追加元素
angular.module("com.ngnice.app").directive('bfFieldError', function bfFieldError($compile){ return { restrict: 'A', require: 'ngModel', link: function(scope, element, attrs, ngModel){ var subScope = scope.$new(true); subScope.hasError = function(){ return ngModel.$invalid && ngModel.$dirty; }; subScope.errors = function(){ return ngModel.$error; }; var hint = $compile('
- { {name | error}}
17. 删除数组元素
$scope.array.splice($.inArray(id, $scope.array), 1);
18. 按钮变换,焦点获取
{ {$index + 1}} { {cor.mistake}} { {cor.operator}} { {cor.updatetime | date:'yyyy-MM-dd hh:mm:ss'}} 编辑 删除
$scope.editSec = function (event,id,context) { if(angular.element(event.target).context.innerHTML == "编辑"){ angular.element(event.target).parents("tbody").find("input").attr("readonly","readonly"); angular.forEach(angular.element(event.target).parents("tbody").find("input"),function (data, index, array) { angular.element(angular.element(data).parents("tr").find("a")[0]).context.innerHTML = "编辑"; }) $scope.checkEdit = false; angular.element(event.target).parents("tr").find("input").removeAttr('readonly').focus(); angular.element(event.target).context.innerHTML = "保存"; }else{ $scope.updateCor(id,context); $scope.checkEdit = true; angular.element(event.target).parents("tr").find("input").attr("readonly","readonly"); angular.element(event.target).context.innerHTML = "编辑"; } }