如何查看一个DOM元素对应的scope:在浏览器调试器中选中要查看的元素,在控制台中输入$0,输出DOM本身;输入angular.element($0).scope(),输出DOM对应的scope
scope和javascript对象一样,采用原型继承。
和原型链原理类似,子scope可以通过原型链读取父scope的值,但是,写会在子scope本身!隔离作用域(isolate scope)直接继承自scope原型本身,不继承自父scope!只能通过directive的scope属性指定其中的值,但是.$parent指向其真正的父作用域。详见: http://stackoverflow.com/a/16705183
$scope内定义的函数,在被调用时,this 为directive对应的scope,而非定义他的scope。详见:http://jsfiddle.net/mrajcok/sbZw7/
$rootScope:根作用域
$scope与scope的区别:$scope只在使用依赖注入时才起作用,scope是特定函数的参数。$scope一般用于 controller 和 service。
$scope
.$apply():通知angular scope有变动。
.$digest():脏值检查。angular的具体实现,详见:http://blog.sae.sina.com.cn/archives/1539
.$watch():在scope内添加监听器。
.$broadcast():向父scope传播事件。包含自身作用域
.$emit():向子scope传播事件。包含自身作用域
.$on():监听事件。
.$destroy():销毁scope。
指定作用域(scope)。
声明一个controller,既可以使用app.controller()方式,也可以用全局同名函数代替。但是angular不推荐此种用法
angular.module('myApp', []) .controller('myController1', function() { // controller code }); function myController2() { // controller code }
使用as,可以将controller暴露在scope中。例:<div ng-controller="myCtrl as ctrl">
支持多种指令书写方式
<div ng-controller="Ctrl1"> <span ng-bind="name"></span> <span ng:bind="name"></span> <span ng_bind="name"></span> <span data-ng-bind="name"></span> <span x-ng-bind="name"></span>
<span my-dir="exp"></span> <my-dir></my-dir> <!-- directive: my-dir exp --> <span class="my-dir: exp;"></span> </div>
directive名称转换规则:过滤掉x-和data-前缀。用驼峰命名法替换:,-,_分隔符
如果想在普通属性中使用绑定,比如src,href,则使用ng-*的属性名,用来防止浏览器解析DOM时闪烁
<a ng-href="img/{{username}}.jpg">Hello {{username}}!</a>
ng-app:确定angular app的作用范围
ng-csp:让angular运行在 CSP 模式下。为防止XSS攻击,此模式下限制使用 eval 和 Function(String) 的使用(用“ getterFn ”代替)。影响性能,慢30%。用在html标签上。
ng-controller:声明controller
ng-view:声明视图
ng-bind:绑定元素内容,和{{}}类似
ng-init:给scope赋值
ng-model:声明元素绑定的作用域内的属性
ng-repeat:迭代元素。为每个迭代元素创建新的作用域
ng-repeat-start & ng-repeat-end:从start标记的元素开始,到end标记的元素结束,作为循环体进行循环输出,而不是只限定循环同一个父元素的子元素。
ng-list:
ng-options:为select标签生成从属的option
迭代数组内的元素:
label for value in array
select as label for value in array
label group by group for value in array
select as label group by group for value in array track by trackexpr
迭代对象内的属性(key,value是为对象内属性的名称和值取名用来迭代):
label for (key , value) in object
select as label for (key , value) in object
label group by group for (key, value) in object
select as label group by group for (key, value) in object
ng-cloak:在加载或编译完成之前,隐藏元素。完成之后删除该属性。class="ng-cloak"也可以
ng-style:<h1 ng-style="{color:selectedColor}"> 设置一个json,value是scope内的属性
ng-class:推荐两种用法
1 <div ng-class="{'selected': isSelected, 'car': isCar}"></div> 用于应用多class
2 <div ng-class="{true: 'active', false: 'inactive'}[isActive]"></div> 用于切换特定class
ng-show、ng-hide:显示隐藏元素
ng-disabled:指定disabled属性时使用
ng-include:
* 任何在ng-tag内的字符串本质上都是表达式,所以如果明确引入一个文件,需要再嵌套一层引号,以表明这是一个字符串而非变量。
详见:http://stackoverflow.com/questions/13943471/angularjs-ng-include
<li ng-repeat="node in node.nodes" ui-tree-node ng-include="'nodes_renderer.html'">
ng-open:表达式为true时,给元素添加名为 “open” 的 attribute
priority:指定directive的执行优先级。默认值0。数值越大,优先级越高。compile函数按照优先级顺序执行,preLink越早执行,而postLink则刚好相反,更晚执行。同数值的directive执行顺序不定。
terminal:指定当前priority为能执行的directive的最低数值,比当前priority低的directive都不再被执行。
restric:匹配模式,可同时指定多个值
E - tag名: <my-directive></my-directive>
A - Attribute (默认值): <div my-directive="exp"></div>
C - Class: <div class="my-directive: exp;"></div>
M - 注释: <!-- directive: my-directive exp -->
template:指定模板。可以是字符串,也可以是一个函数 function(element, attrs) { ... return “template content string” }
templateUrl:指定模板的URL 。可以是字符串,也可以是一个函数 function(element, attrs) { ... return “template URL ” }
replace:是否用模板内容替换directive,默认值false。替换模式下,模板需要有基本的包围容器(也就是container block),会把标签的attribute和class都复制给这个包围容器。
transclude:用 ng-transclude 来指定一个插入位置,使directive内的html内容插入到指定了ng-trasclude标签的元素。transclude的scope继承自父scope,和directive的scope是同级的兄弟scope。
true:插入directive的内容
'element': 将directive本身和他的子元素都算做transclude一部分。多用于 ng-repeat 和 ng-switch。详见:http://stackoverflow.com/a/18457319 要起作用,必须与 replace:true 一起使用,详见:https://github.com/angular/angular.js/issues/3368
scope:为directive指定作用域。如果不指定scope,则scope默认继承父scope。
true:一个元素有多个directive同时请求,只创建一个scope。
{}:生成一个隔离作用域(isolate scope),而不是继承自父作用域,并且指定作用域内变量与元素的attrbute的绑定关系,key:作用域内的变量,value:attribute。不指定attr,则使用该属性名称作为attr。
@ or @attr:将父scope内执行的attribute的内容单向绑定为变量,结果是一个字符串。支持{{}}表达式。
= or =attr:将父scope内的变量双向绑定为变量。如果父作用域内没有对应名称的变量,则抛出异常。使用 =? or =?attr 可以避免此抛出异常
&
or &attr
:将父scope内执行的表达式绑定为函数。取值时使用函数:foo()。多用来作为directive的API暴露出来
require:指定directive所需要的controller
(null) - 从当前元素查找需要的controller。如果没找到,抛出异常
? - 从当前元素查找需要的controller。如果没找到,赋值null
^ - 从父元素查找依赖的controller 。如果没找到,抛出异常
?^ - 从父元素查找依赖的controller。如果没找到,赋值null
controller:在pre-link之前,实例化一个directive所需要的controller。可以共享给其他directive。多用来作为directive的API暴露出来。
function controller($scope, $element, $attrs, $transclude) { ... }。
$scope:作用域
$element:当前元素的JQLite包装
$attrs:attribute的hash map
$transclude:处理嵌套的函数,参数为另一个参数列表为function([scope], cloneLinkingFn)的函数。等同于link当中的 transcludeFn。
controllerAs:在directive的scope内指定controller的别名,也就是将controller放入scope内。
compile:生成 link 函数。
类似于模板引擎的预编译函数。link 函数类似于模板引擎的 template function,作用是与 scope 进行连接,返回html DOM。
function compile( tElement, tAttrs , transclude ) { ... }
tElement:模板元素的JQLite包装。
tAttrs:模板元素的attribute
transclude:不建议使用 。 从 angular 1.2 开始转移到 link 中。详见:http://www.bennadel.com/blog/2561-Changes-In-Transclude-Function-Availability-In-AngularJS-1-2.htm
compile函数的返回值有两种形式
1 直接返回一个函数,作为 postLink 执行
2 返回一个 object hash:{ pre : function() {}, post : function() {} }
function preLink or postLink (scope, iElement, iAttrs, controller, transcludeFn) { ... }
scope:作用域
iElement:当前元素的JQLite包装
iAttrs:元素的attribute
controller:directive所需的controller。与require有关。
transcludeFn:处理嵌套的函数。transcludeFn( [scope], function(clone) { ... } ); 其中clone为被transclue元素的DOM。replace:true 时,将包含directive自身。等同于controller当中的 $transclude。
compile,controller,link的执行顺序如下。详见:http://plnkr.co/edit/CW7cF0?p=preview
(all`s compile) -> controller -> preLink -> (sub`s controller -> preLink -> (recurse) -> PostLink ) -> PostLink
同级directive的执行顺序依赖priority,preLink降序,postLink升序。
compile用来定义如何输出DOM。
controller的操作基本都是针对scope,而不是操作DOM。因为此时,sub directive的link还没有执行。多用来暴露API。
postLink多用来操作DOM,挂载事件。因为此时自身包括sub的DOM已经稳定。
link:compile 函数返回值的 shortcut。指定compile,link属性会被忽略。
attr对象:
$set:attrs.$set('ngModel', 'new value');
$observe:attrs.$observe('ngModel', function(value) { ...});
都是单例。
provider:
1 接受一个函数,返回值对象包含$get()方法。this.$get()可以被注入依赖。
2 接受一个对象,其中要包含$get()方法。
只有provider可以被注入到.config()函数内,返回值为provider本身,而非this.$get()的返回值,并且注入名称要加上'Provider'。
factory:provider的封装。接受一个函数(可以被注入依赖),以后调用时返回这个函数的返回值。
function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); }
service:factory的封装。接受一个构造函数(可以被注入依赖),返回这个构造函数的实例。返回的都是一个实例,不再新生成,保持单例。
function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); }
value:变量,可修改
function value(name, value) { return factory(name, valueFn(value)); }
constant:常量,不可修改
function constant(name, value) { providerCache[name] = value; instanceCache[name] = value; }
$interval():等于setInvertal。$interval.cancel:取消interval
$timeout():等于setTimeout。
// TODO:
$scope
$rootScope
$http
$compile
$attrs
$provide.decorator
必须手动引入angular-route.js文件
when:配置路径
otherwise:配置默认跳转
angular.module('myApp', ['ngRoute']).config(function($routeProvider) { $routeProvider .when('/', { templateUrl: 'views/main.html', controller: 'MainCtrl' }) .when('/day/:id', { templateUrl: 'views/day.html', controller: 'DayCtrl', }) .otherwise({ redirectTo: '/' }); })
resolve:在切换到新view之前,加载需要的数据。resolve是一个map,key为依赖的名字,value为被作为依赖的对象
angular.module('myApp', ['ngRoute']).config(function($routeProvider) { $routeProvider .when('/account', { controller: 'AccountCtrl', templateUrl: 'views/account.html', resolve: { account: function($q) { var d = $q.defer(); $timeout(function() { d.resolve({ id: 1, name: 'Ari Lerner' }) }, 1000); return d.promise; } } }) });
angular.module('myApp').filter('piglatin', function() { return function(text) { text = text || ''; return 'my' + text; } });
每次@digest都会触发filter两次,严重影响性能。所以最好不要在view中直接使用filter,而是放在controller中提前过滤数据
必须手动引入angular-animate.js文件,需要angular版本1.2.4+
当DOM元素发生对应事件时,添加相应的class
.ng-enter .ng-enter-active
.ng-leave .ng-leave-active
.ng-move .ng-move-active
或者使用service:$animate
如何在angular中使用 stopPropagation 和 preventDefault
<a ng-click="doThing($index); $event.stopPropagation();">x</a>