数据双向绑定的框架javascript
提供数据绑定,DOM指令。angular,定义了一套规则,开发中就必须遵照规则,这套规则为项目提供了一套解决方案。css
模块
,组件
,模板
,元数据
,数据绑定
, 指令
,服务
,依赖注入
,控制器
,过滤器
,路由
html
启动/引导 (Bootstrap)
做用:启动程序入口(bootstrap方法来引导Anuglar引用程序)
识别应用程序中的根做用域$rootScope
经过依赖注入体系注册服务的提供商java
属性型指令 (Attribute Directive)
是指令分类的一种。
做用:监听或修改其它HTML元素,属性,组件的行为。通常做为HTML属性。
例如: ng-controller 当前所在的元素添加控制器。node
组件(Component)
做用:把数据展现到视图(view),并处理全部的视图显示和交互逻辑的Angular类。angularjs
在类中定义组件的应用逻辑 ( 它被用来为视图提供支持 ) , 组件经过一些由属性和方法组成的 API 与视图交互。npm
组件是Angular系统中最重要的基本构造核心之一。json
数据绑定(Data Binding)
做用:将数据展现给用户,用户操做作出应答。
将这些数据显示到HTML中,添加事件监听器,获取数据变化,更新数据。bootstrap
在双向数据绑定中,数据的属性值会从具备属性绑定的组件传到输入框。经过事件绑定,用户的修改数据传回到组件,把属性值设置为最新的值。设计模式
Anuglar 在每个JS事件周期中一次性处理全部的数据绑定,它会从组件树的根部开始,用深度优先的方式! (数据绑定在模板与对应组件的交互中起到了重要做用)
组件从技术角度上看就是一个指令。组件位置很独特,并在Angular中位于中心地位。
插值表达式
属性绑定
事件绑定
attribute绑定
css类绑定
样式绑定
基于ngModel的双向数据绑定
单向绑定 (ng-bind) 和双向绑定(ng-model)
ng-bind 单项数据绑定 ($scope -> view) 用于数据显示,简写形式 {{}}
区别:页面没有加载完毕{{val}} 会直接显示到页面,知道Angular渲染该绑定数据.
ng-bind则是在Angular渲染完毕后将数据显示.
ng-model 双向数据绑定 ($scope -> view and view -> $scope) ,用户绑定值会变化的表单元素等.
每次绑定一个东西到 view 上时 AngularJS 就会往 $watch 队列里插入一条 $watch,用来检测它监视的 model 里是否有变化的东西。
当浏览器接收到能够被 angular context 处理的事件时,$digest 循环就会触发。$digest 会遍历全部的 $watch 。
一次更新数据操做,至少会触发两次$digest() 循环,$gigest循环的次数达到了10次(超过10次后抛出一个异常,为了防止无限循环)
依赖注入(Dependency Injection)
须要依赖的缘由:无法控制这实例背后隐藏的依赖。 当不能控制依赖时,类就会变得难以测试。
按需注入,须要才注入。
经过给函数添加形参,使得caller传入的参数的callee接收的参数逻辑分离,使得函数经过依赖管理系统仅仅须要声明需呀的协做对象,而不须要知道从哪里来,如何建立等问题。
依赖注入便是设计模式,同时又是一种机制:当应用程序的一些组件须要另一些组件的时候,使用依赖注入机制来建立被请求的部件并将其注入到发出请求的组件中。
提供类的新势力的一种方式,负责处理好累所需的所有依赖。大多数依赖都是服务。Angualr使用依赖注入提供所需的组件以及组件所需的服务。
angular构建应用程序时:定义许多精简的小部件,每一个小部件只作一件事,而且作好它,而后在运行期把这写精简小部件装配在一块儿组成应用程序。
依赖注入的核心是:注入器(Injector),这个注入器根据须要返回被依赖的部件。injector.get(token) 方法返回与token(令牌)参数相关的依赖部件。
令牌是一个Angular中类型.绝大多数类方法都接受类名或字符串。Angular会把这些类名称和字符串转换成令牌。当调用injector.get(Foo)时,注入器返回用Foo类生成的令牌所对应的依赖值,该依赖值一般是Foo 类的实例。
注入器(Injector)维护一个令牌与相应依赖值的对照表(map)。若是注入器不能找到一个令牌对应的依赖值,它就会使用提供商(Provider) 来建立一个依赖值.
提供商是建立依赖实例的“菜谱”之一,这个实例会与一个特定的令牌关联起来。
只有当注入器内部的提供商注册表中存在于令牌对应的提供商时,注入器才能为这个令牌建立一个依赖值。
angular会为每一个注入器注册不少angular内建提供商。
一般注册提供商的最佳时间是在应用程序引导(Bootstrap)的时候。
依赖注入渗透在整个框架中,而且被处处使用。
注入器负责维护一个 容器 ,用于存放它建立过的服务实例。
注入器能使用 提供商 建立一个新的服务实例。
提供商 是一个用于建立服务的“配方”。
把 提供商 注册到注入器。
指令(Directive)
指令是一个Angular类
做用:建立和重塑浏览器DOM中的HTML元素,负责与HTML元素的应答系统
指令包括的类别:
组件(Component): 用来把程序逻辑和HTML模板组合起来,渲染出应用程序的视图。组件通常表示成HTML元素的形式,
属性型指令:能够监控和修改其它HTML元素,HTML属性,DOM属性,组件等行为。
结构性指令:负责塑造HTML布局。通常是经过添加,删除或操做HTML元素及其子元素来实现的。
注入器(Injector)
Anuglar依赖注入系统中的一个对象。
做用:从缓存中找到一个"有名字的依赖"或者利用一个已注册的提供商来建立依赖。
注入器是一个维护服务实例的容器,存放着之前建立的实例。
若是容器中尚未所请求的服务实例,注入器就会建立一个服务实例,而且添加到容器中,而后把这个服务返回给Angular。
当左右服务都被解析并返回时,Angular会以服务为参数去调用组件的构造函数。
插值表达式(Interolation)
属性数据绑定的形式:位于双大括号中的模板表达式会被渲染成文本。
模块(Module)
应用程序一般由不少个模块组装而成。
模块导出东西--类,函数,值,供其它模块引入。
把应用写成一组模块,每一个模块只导出同样东西。
模块:具备单一用途的内聚代码块
一个模块加载器来按需加载模块并解析模块的依赖关系。
模块库
有些模块是其它模块的库
Anuglar 自己就是经过npm包发布的一组模块库, 以@angular为前缀。
每一个库包含一个 封装桶 。是公开的外观层(facade) 包括一些逻辑相关的私有模块。
管道(Pipe)
管道是一个函数
做用:把输入值换成输出值供视图显示。
提供商(Provider)
做用:依赖注入系统依靠提供商来建立依赖实例。
它把一个供查阅用的令牌和代码关联到一块儿,以便建立依赖值。
服务是一个类,具体实现一件事情,具备专一,良好定义的用途。
几乎任何东西均可以是一个服务。
添加,删除或操做元素和其各级子元素来塑造或重塑HTML布局的指令。
例如:ngIf
模板(Template)
模板是大块HTML。
做用:渲染视图
Angular会在指令和组件的支持和持续指导下,渲染视图。
装饰器 (Decorator | Decoration)
装饰器是一个 函数,这个函数将元数据添加到类,类成员(属性,方法)和函数上。
angular 使用自身一套装饰器来实现应用程序各个部分之间的相互操做。
应用程序的指令,一个程序中必需要有该指令
<body ng-app></body>
数据绑定的指令,将数据绑定到应用程序中
<input type="text" ng-model="msg" />
绑定数据,它的简写方式直接在元素中{{key}}
<div>{{ msg }}</div>
当页面加载完毕,angularjs启动起来,首先回去页面中寻找ng-app指令,找到后初始化应用程序。
ng-app告知angular这个应用是绑定那个DOM元素,也就是程序初始化的元素时body,因此之后绑定的指令可以生肖的只能在ng-app所在的元素中
angularjs找到ng-model指令,它将该指令对应数据绑定在该程序的做用域中。
angularjs找到ng-bind或者{{key}} 指令,它将数据渲染到该元素内。
angularjs遍历其它指令,完毕后,就可使用应用程序。
表示初始化应用程序中的变量,多个变量用; 注意定义多个变量不能用逗号,只能用分号;
<div ng-init="msg='hello wrold'; info='您输入的信息为:'" ng-controller="msg"> <input type="text" name="" id="" value="" ng-model="msg" /> <span ng-bind="msg"></span> <span>{{ info }}</span> <span>{{ msg }}</span> </div>
经过angular.module方法
该方法有两个参数
参数1,表示程序的名称。
参数2,表示依赖服务(依赖集合)
依赖就是达到某个目的的必要条件(不可或缺)。
var app = angular.module('app', []);
定义控制器
App的controller方法:
两个参数
第一个参数表示控制器的名称
第二参数表示控制器的构造函数
参数是你须要的数据,须要什么能够传递什么,这样在构造函数中就可使用它,若是没有传递就没法使用
ng-controller 控制应用程序的,后期对某一视图动态改变的做用
定义控制器
app.controller();
参数1:控制器名称
参数2:控制器的回调函数(构造函数)
回调函数的参数是所须要的数据,须要什么能够传递什么,这样在回调函数中就可使用它,若是没有传递就没法使用
angular参数注入:想用什么东西就在参数中注入。
不要再控制器中操做 DOM。 经过指令完成。
经过控制器完成的功能命名控制器,并以字符串Ctrl结尾,例如:(HomePageCtrl)
控制器不该该全局中定义
尽量精简控制器,将通用函数抽线为独立的服务
经过方法引用进行跨控制器通信(一般是子控制器与父控制器通信) 或者 $emit,$broaadcast 以及 $on 方法。发送或广播的消息应该限定在最小的做用域。
置顶一个经过 $emit,$boradcast 发送的消息列表而且窒息的管理以防止命名冲突
在须要格式化数据时,将格式化逻辑封装成 过滤器
<div ng-controller="msg"></div>
// 控制器 app.controller('msg', function ( $scope ) { console.log( this ); console.log( arguments ); });
$scope: 用来实现数据与视图的链接,在$scope上定义的数据,能够用视图在上,那么视图上绑定的数据能够在$scope上也能获取到
$scope 是经过原型式继承实现, 子做用域会继承父做用域中的变量,可是能够为子做用域添加变量还重写符做用域中的变量。
scope特色
$scope 是一个 POJO 简单的Java对象
$scope 提供了一些工具方法$watch()/$apply();
$scope 表达式执行环境,或者说做用域
$scope 是一个树型结构,与DOM标签平行
每个angularjs应用都有一个跟做用域$rootScope,位于ng-app上
$scope 能够传播事件,相似DOM事件,能够向上下能够向下
$scope 不只是MVC 的基础,也是后买呢实现双向绑定的基础,应用开始先找rootScope,而后把下级scope附加到rootScope上从而造成树型结构.
scope生命周期
建立(creationd)
在建立控制器或指令时,angularjs会用$onjector建立一个新的做用域,并在这个新建的控制器或指令时把做用域传进去
连接
scope对象会附加或连接到视图。这些做用域将会注册到 angular上下文中发生变化时须要运行的函数
$watch -> 注册监控(Watcher registration) 变化时执行 回调函数
更新
事件循环执行时,顶级的$rootScoep和每一个子做用域都执行本身的脏值检查。某个监控函数监控变化,检测到变化后,$scope会触发指定的回调函数。
销毁
当scope在视图中再也不须要时,会清晰和销毁本身。
$scope.$destory();
ng-eventsName
例如:ng-click
若是想在回调函数中传递参数,在圆括号里面直接添加
执行的做用域是$scope,当前的做用域
参数经过元素调用时传递的参数一致,最后一个参数为事件对象
<button ng-click="clickBtn('info',$event)" ng-bind="red"></button>
// 事件 $scope.clickBtn = function ( msg, ev ) { }
ng-show 表示显示元素指令
ng-show 显示元素:true显示,false隐藏
ng-hide 隐藏元素:true隐藏,false显示
<span ng-show="isShow">1</span> <span ng-hide="isShow">2</span>
插值和数据的过程当中能够应用表达式
的绑定过程咱们能够应用表达式
在表达式中不只仅能够用运算符,还能够应用js提供的方法
<div>{{'面积是:' + width * height}}</div> <div>{{ msg.toUpperCase() }}</div>
用来对绑定数据显示时候处理
{{key | filter}}
currency
格式化数字为货币格式
<div>{{msg | json}}</div> <div>{{ msg | currency }}</div>
filter
过滤数组项
<div ng-controller="filters"> <div>{{ color | filter : 'n' }}</div> <div>{{ color | filter : filterChar }}</div> <div>{{ color | filter : filterFirstStr }}</div> </div> <script type="text/javascript"> // app var app = angular.module('appBody', []); // controller app.controller('filters', function ( $scope ) { $scope.color = ['tan', 'khaki', 'Pink', 'cyan']; // a 过滤出来 $scope.filterChar = 'a'; $scope.filterFirstStr = function ( val ) { // 匹配首字母大写 return val[0] === val[0].toUpperCase(); } }); </script>
date
日期过滤器,格式化日期
<div ng-controller="dates"> <span>{{ iDate | date : 'yyyy' + '年'}}</span> <span>{{ iDate | date : 'MM' + '月' }}</span> <span>{{ iDate | date : 'dd' + '日' }}</span> <span>{{ iDate | date : 'HH' + ':' + 'mm' }}</span> <p>{{ iDate | date : 'yyyy年 MM月dd日 HH:mm' }}</p> </div>
// app var app = angular.module('appBody', []); // controller app.controller('filters', function ( $scope ) { $scope.color = ['tan', 'khaki', 'Pink', 'cyan']; // a 过滤出来 $scope.filterChar = 'a'; $scope.filterFirstStr = function ( val ) { // 匹配首字母大写 return val[0] === val[0].toUpperCase(); } });
limitTo
截取过滤器
参数表示截取的长度
这个过滤器不只仅能够截取字符串,还能够截取数组
<div>{{ color | limitTo : 2 }}</div> <div>{{ msg | limitTo : 3 }}</div>
字符串大小写
uppercase 将字符串转化成大写
lowercase 将字符串转化成小写
这个过滤器痛对数据直接调用字符串方法toUpperCase和toLowerCase效果是同样的
可是angular建议使用过滤器
过滤器能够被复用
不建议在表达式中使用方法(除特殊状况)
<div>{{ msg | uppercase }}</div> <div>{{ msg | lowercase }}</div> <div>{{ msg.toLowerCase() }}</div>
number过滤器
是一种数字类型数据过滤器
参数表示截取小数位置
该过滤器是将数字以每三为分割渲染的
不传递参数默认保留三维,最后一位四舍五入
<div>{{ num | number }}</div> <div>{{ num | number : 4 }}</div>
orderBy
对数组进行排序的过滤器
参数1,数组中每一个成员排序的索引属性名称
参数2,正序仍是倒序 (true反序)
<div>{{ color | orderBy : '' : true }}</div> <div>{{ color | orderBy }}</div>
定义
经过app提供的filter方法来定义过滤器 app.filter();
接受两个参数
参数1,过滤器的名称
参数2,过滤器的回调函数(构造函数)
回调函数必须返回一个函数,这个函数在每次数据更新时候执行。
回调函数只执行一次
返回的函数,能够接受过滤器使用时传递的参数,可是第一个参数永远是绑定的数据,后的参数才是传递的参数,参数的顺序痛使用时传递参数的顺序一致。
调用
使用方式同内置过滤器同样,在管道符号后面添加过滤器的名称,经过:
添加参数
使用小驼峰命名
尽量使过滤器精简。 过滤器在 $digest loop 中频繁被调用,过于复杂的运算使得整个应用执行缓慢。
在过滤器中只作一件事. 更加复杂的操做能够用pipe来实现.
<!--自定义过滤器--> <input type="text" ng-model="msg" /> <div>{{ msg | CaseChar }}</div> <div>{{ msg | CaseChar : true }}</div>
app.filter('CaseChar', function () { return function ( val, FirstToUpper ) { if ( val ) { // FirstToUpper 参数 表示第一个字母大写 if ( FirstToUpper ) { // 第一个字母 大写 val = val.replace(/^[a-z]/, function ( match, $1 ) { return match.toUpperCase(); }); } // 存在输入的val 值 转驼峰 return val.replace(/_([\w])/g, function ( match, $1 ) { return $1.toUpperCase(); }); } return ''; } });
当对表单元素form添加name属性时候,angular会自动将该属性的值添加到做用域中,而且该属性具备表单验证的属性. 具备FormContorller
对象
$dirty 表单是否被用户输入过,输入过,值为true,没有输入过值为false
$pristine 表单是否被用户输入过,输入过,值为false,没有输入过值为true
$valid 输入的值是否合法,合法值为true,不合法为false
$invalid 输入的值是否合法,合法值为false,不合法为true
$valid 属性值为true时,全部表单元素必须$valid都是true
$invalid 属性为true时,只要有一个表单元素$invalid之为true
$dirty 属性为true时,只要有一个表单元素被修改过,$dirty值为true
$pristine 属性为true时,全部的元素未被修改过,那么$pristine值为true
<form name="appForm"> <label for="">用户名:</label> <input type="text" name="username" ng-model="uname" ng-maxlength="5" id="" value="" /> <span ng-show="appForm.username.$invalid">输入的长度大于5</span> </form>
<form name="appForm"> <!-- 兼容 HTML5 表单元素 --> <label for="">邮箱:</label> <input type="email" name="emial" ng-model="emailModel" id="" value="" /> <span ng-show="appForm.emial.$invalid">输入内容必须是emial</span> </form>
<form name="appForm"> <!--使用 ng-pattern 匹配正则--> <input type="text" name="txt" ng-model="passModel" ng-pattern="/^\d{4,6}$/" id="" value="" /> <span ng-show="appForm.txt.$invalid">输入的内容必须是4-6位数字</span> </form>
获取app并执行(程序入口指令会提供一个run方法),一般会在该方法中访问根做用域,该方法接收一个函数做为参数,
函数中的this指向window,所以能够访问到全局做用域下的变量。
arugments默认没有值,须要什么值,须要经过参数注入来供函数内使用。
做用:处理的是根做用域,所以一般要将$rootScope传递进来.
app.run(function ( $rootScope ) { });
controller与做用域
var app = angular.module('main', []); app.controller('parentCtrl', function ( $scope ) { $scope.clickParent = function () { $scope.msg = 'parentScope'; } }).controller('childCtrl', function ( $scope ) { $scope.clickChild = function () { $scope.msg = 'childScope'; } }); // rootScope app.run(function ( $rootScope ) { $rootScope.msg = 'rootScope'; }) console.log( app );
ng-disabled
表单是否能够操做
<input type="text" ng-disabled="isable" name="" />
ng-readonly
表单是不是只读
<input type="text" ng-readonly="isable" name="" id="" value="" />
ng-checked
选择框是否被选中
值为true:选中
值为false:未选择
<input type="checkbox" ng-checked="isabel" name="" id="" value="" />
ng-change
监听输入表单内容的改变,当表单内容改变的时候就会触发.
改变的时候,须要知道数据是否更改,须要加上ng-model
<input type="text" ng-model="msg" ng-change="change()" name="" />
app.controller('inp', function ( $scope ) { $scope.change = function () { alert($scope.msg); } });
ng-submit
对form表单元素绑定submit事件,当点击表单中submit元素时候,会触发该事件
ng-submit须要搭配标签form使用
<form name="forms" ng-submit="submit()"> <input type="text" name="" ng-model="msg" id="" value="" /> <input type="submit" value="提交"/> </form>
ng-src
浏览器打开页面,浏览器不认识ng-src属性,所就不会发请求,那么当ng-src绑定的数据imgSrc有数据的时候,angular会把这个数据赋值给src属性,让img标签发送一个请求
<img ng-src="{{imgSrc}}" />
ng-href
当浏览器打开页面的时候,元素不具备href属性,就不具备连接行为(为#号却可以点击),ng-src对这一现象作了优化,当ng-href绑定的数据加载成功后,将这一属性值,赋值给a标签的href属性,让a标签具备链接的行为。
<a ng-href="{{Url}}">跳转</a>
ng-class
是用来动态建立类的一个指令,它的只是一个对象,对象中的舒心表明类的名称,属性值只能是一个Boolean
true,会将该类名添加到元素的class属性中。
false,会将该该类名从该元素的class属性中删除。
<div ng-class="{red: ngClassInfo>4, green: ngClassInfo <=4 }">{{ ngClassInfo }}</div>
ng-style
用来动态建立样式,它的值是一个对象,对象中的属性表示css属性,值为css属性值。
<div ng-style="{background: 'tan', width: '100px', height: '100px'}"></div>
ng-if
判断指令.
angular中没有ng-else指令,能够经过ng-if模拟
<div ng-if="isable">111111111111</div> <div ng-if="!isable">222222222222</div>
ng-switch
分支判断
当元素这是了ng-switch,元素是一个ie分支判断的模板,全部分支都要包含在该元素内。
经过on指令来设置判断条件,ng-switach和on配合使用
ng-switch-when="key":表示判断某一条件,当on的绑定的数据值为该分支对应的值的时候,执行。
<!--须要将分支判断的元素放入 ng-switch 容器中--> <div ng-switch="" on="switchInfo"> <div ng-switch-default="">默认</div> <div ng-switch-when="first">1111</div> <div ng-switch-when="second">2222</div> </div>
ng-repeat
循环渲染模板
语法: ng-repeate="item in list";
内置变量$index
循环的索引值,从0开始计数$first
第一次循环是true,其它次循环是false$last
最后一次循环是true,其它此循环是false$middel
除去第一次和最后一次值是true $even
偶数次循环是true,奇数次循环是false$odd
奇数次循环是true,偶数次循环是false
<ul> <li ng-repeat="item in colors" ng-class="{red: $odd}">{{ item }} --- {{'索引值:'+$index}} --- {{ $middle }}</li> </ul>
ng-include
模板定义在单独文件中,经过ng-include引入进来.
ng-include="url" 注意url是字符串
<div ng-controller="aMsg"> <div ng-include="'a.html'"></div> </div>
// 数据传输 var aMsgApp = app.controller('aMsg', function ( $scope ) { $scope.msg = '载入成功'; });
使用 ng-bind 或者 ng-cloak 而 不是使用 {{}} 插值方式,防止页面渲染闪烁
避免在插值中使用复杂代码
须要动态设置 <img>
的 src 时使用 ng-src 而不使用 src中嵌套 {{}}
须要动态设置 <a>
的 href 时使用 ng-href 而不是用 href 中嵌套 {{}}
经过对象参数和scope变量做为值来使用 ng-style 指令, 而 不是使用 scope 变量做为字符串经过 {{}} 用于 style 属性。
参数1: 指令的名称
参数2: 构造函数,自定义指令式,只执行一次,将一些复杂业务逻辑放在该函数中,最后改函数返回是一个对象(用来描述指令)
规则:
使用小驼峰命名。
在link function 中使用 $scope 。 在compile中, 定义参数的post/pre link functions 将在函数执行时被传递,没法经过依赖注入改变它们。
指令添加自定义前缀避免与第三方指令冲突
可复用组件建立独立做用域
使用 scope.$on('$destroy', fn) 来清除. 这点在使用第三方指令的时候特别有用.
restrict: 自定义指令的类型
E,该指令是一个自定义元素(element)
A,该指令在元素时属性上(attributes)
C,该指令在元素的类上(class)
M,注释指令(comment)
template: 传递的是模板字符串
templateUrl: 模板文件的路径
replace: false
是否替换原有的元素,true会替换掉原有的元素,false不会替换掉元素。
当设置true时,会对controller中使用的参数$element 和 $attrs 有影响
controller
用来定义自定义指令的做用域。
this 指向的controller{}空对象
arguments默认状况下是一个空数组,须要参数注入。
$scope 该指令的做用域
$element 该指令的元素
$attrs 该指令的元素的属性
// directive() 自定义指令 app.directive('curtoms' , function () { console.log(111); return { // 指令类型 restrict: 'EAC', // 模板字符串 // template: '<h1>自定义指令</h1>', // 模板文件获取 url templateUrl: 'a.html', // replace表示是否替换原来的元素,true是替换,false不替换 // replace: false, replace: true, controller: function ( $scope, $element, $attrs ) { // this 指向 controller{} 空对象 console.log( $scope, $element, $attrs ); } } });
scope
隔离自定义的做用域的属性,经过对其社会字一个对象来隔离指令的做用域。
若是值是true或者false,指令的做用域就会忽略自身做用域,而去寻找父级做用域中的变量。
若是值是空对象{} ,做用域会指向该空对象
directive返回对象中的scope和controller
自定义指令中,scope属性对controller的影响:
若是scope的值是true,在controller中,定义与父做用域中相同变量时,自定义指令中的变量不会受到反作用于中的变量的影响。
若是scope是一个false,在controller中,定义与父做用域相同变量时,该变量与父做用域中的变量同步(同时修改,数据双向绑定)
若是scope是一个对象,在controller中,定义与父做用域相同的变量时,自定义指令中的变量不会收到父做用域的变量影响。
app.directive('myCutom', function () { return { restrict: 'E', template: '<h1>{{ msg }} -- {{ title }}</h1>', // scope: {}, // scope: true, scope: false controller: function ( $scope, $element, $attrs ) { $scope.title = 'aaaa'; $scope.msg = 'xixixi'; } } });
@修饰符
能够屏蔽模板中变量去controller做用域中寻找值的过程,而是让其去该自定义指令所在元素的属性中寻找数据变量. 忽略自定义指令的scope。
@修饰符会去自定义指令中所在元素的属性去寻找。
属性值是插值传入,做为普通属性处理。
<my-custom my-title="{{title}}"></my-custom>
app.directive('myCutom', function () { return { restrict: 'E', template: '<h1>{{ msg }} -- {{ title }}</h1>', scope: { // 告知 自定义指令 不须要从 本身的做用域中寻找 变量 title: '@myTitle' }, controller: function ( $scope, $element, $attrs ) { $scope.title = 'aaaa'; $scope.msg = 'xixixi'; } } });
=修饰符
经过在scope属性中定义含有=修饰符的变量时,能够取得父做用域中的变量,经过属性映射.
做用:自定义指令做用域中变量与父做用域的双向绑定过程.
注意:自定义元素中的属性值是一个父做用域中的一个变量,在自定义指令中看成一个变量来处理。
template,中的数据和 父级的做用域$scope,数据绑定
tempalte: '<h1>{{title}}</h1>',
app.controller('main', function ( $scope ) { $scope.title = ''; });
link
操做自定义指令的DOM
link的函数
this指向window
arguments:
1 scope, 指令做用域
2 jqlite 获取自定义元素
3 attrs 自定义指令元素上的属性
// 操做自定义指令元素 // @param {Object} scope 子做用域 // @param {Object} jqlite JQ对象 // @param {Object} attrs 自定义上的属性 link: function ( scope, jqlite, attrs ) { // this -> window var el = jqlite.children('h1').attr('nodeValue', 1); // 使用 data 自定义属性 ,会自动省略 data- for ( var i=0; i<attrs.repeate; i++ ) { jqlite.append( el.clone() ); } }
complie
this指向的是指令描述对象.
参数1: jqlite 获取的自定义元素
参数2: attrs 自定义指令所在元素的属性
返回一个函数, 指向 link 函数
在返回函数中,能够操做自定义指令所在元素.
<div ng-controller="main"> <my-directive data-color="pink"> <h1>嘻嘻哈哈</h1> </my-directive> </div> <script type="text/javascript"> // 建立 app var app = angular.module('app', []); // 建立控制器 app.controller('main', function ( $scope ) {}); // 自定义指令 app.directive('myDirective', function () { return { restrict: 'E', // 自定义指令的编译方法 // @param {Object} jqlite 获取自定义指令元素 // @param {Object} attrs 自定义指令所在元素上的样式 // @return {Function} cb 指代 link compile: function ( jqlite, attrs ) { // this -> compile 对象 return function ( scope, jqlite, attrs ) { // this -> window var color = attrs.color; jqlite.css('color', color); } } } }); </script>
transclude
它告诉自定义指令,要将自定义元素中未知的元素内容插入到已知模板具备ng-transclude指令所在的元素中(添加自定义指令元素中的未知元素)
未知元素:自定义标签中的元素.
告知自定义指令,要将自定义中未知的元素内容插入到已知模板。
条件: 模板标签上具备ng-transclude指令
须要设置 transclude: true.
现象:模板标签会包裹自定义标签内的内容.
app.directive('myDirective', function () { return { restrict: 'E', template: '<div ng-transclude></div>', transclude: true } });
require
自定义指令引用其它指令,做为link()方法的第四个参数.
例如,将ngModel引入到自定义指令中. 在link方法中能够访问到ngModel中的属性值
require: 'ngModel'
// 自定义指令 app.directive('myDirective', function () { // 返回一个描述指令对象 return { restrict: 'A', // 引入其它指令 require: 'ngModel', link: function ( scope, jqlite, attrs, ngModel ) { // $watch 检测某个值 发生改变,触发某个函数 // 当 ngModel 值发生改变, 触发函数 scope.$watch(attrs.ngModel, function () { console.log(ngModel.$viewValue); }); } } });
对一些方法的封装,复用方法更为简便。例如:消息系统,做为消息服务.
使用服务,利用参数注入便可。
大驼峰和小驼峰均可
将业务逻辑封装成服务
将业务逻辑封装成 service 而非 factory
使用 $cacheFactory 进行绘画级别的缓存。 应用于缓存请求或复杂运算的结果。
$timeout
对setTimeout()的封装
app.controller('main', function ($scope, $timeout) { $timeout(function () { console.log(this); console.log(arguments); }, 2000); });
$interval
对setInter();的封装
app.controller('main', function ($scope, $interval) { // 定义一个时间 $scope.date = new Date(); $interval(function () { // 从新定义日期 $scope.date = new Date(); }, 1000); });
$http
异步请求
配置参数:
method: 请求方式 "GET","POSt"
url: 请求的地址
$http 方法执行完后链式调用success(),请求成功的回调函数
POST请求:
经过设置data属性添加POST请求发送数据
params属性添加请求的参数数据
// $http 服务 $http({ method: 'GET', url: 'data/service.json' }).success(function ( res ) { if ( res.errno === 0 ) { $scope.msg = res.msg; console.log(res); } });
$http({ method: 'POST', url: 'demo.json', // 该属性会将键值对转化成url上参数 params: { id: 11 }, // post请求 添加请求数据 data: { username: 'aa' } });
$http.get,$http.post
$http服务中的get请求和post请求简写方式
params 配置请求参数
// get 请求 $http.get('data/service.json', { params: { id: 1 } }) // 请求成功 .success(function ( res ) { console.log( res ); });
// post 请求 // 参数1:url ,参数2:请求携带的数据 $http.post('data/service.json', { id: 1 }) // 请求成功 .success(function ( res ) { console.log(res); });
promise对象
允诺对象,在内部是一个异步操做,当操做完成时,这个对象会实现它的允诺.
特色: 能够无限添加允诺。 必定在某些操做完成时才出发。
规范中允诺对象使用 then方法.
须要各类服务以支持各类功能,也能够手动开启或关闭某些服务以达到相应的功能.
factory()
工厂模式定义自定义服务
参数1:服务名称
参数2:服务工厂方法
返回值:服务对象,这个对象提供其它控制器使用
var app = angular.module('app', []); // 其它控制器使用服务 app.controller('facotryCtrl', function ( $scope, news ) { $scope.msg = news.data; }); // factory 定义 服务 app.factory('news', function () { return { data: '嘻嘻哈哈' } });
service
面向对象建立服务
参数1:服务名称
参数2:服务的构造函数(构造函数中须要使用this来暴露接口)
// 使用 service 自定义服务 app.service('data', function () { this.title = '嘻嘻哈哈'; });
使用组件配合使用:angular-route.js
angular-ui-router.js
用来寻找页面,一般经过配置一些路由来映射一些页面
路由:就是URL到函数的映射
。
须要在程序入口处引入,添加到依赖集合中
angualr.module('app', ['ngRoute']);
ng-view
动态渲染的视图,视图如何渲染根据路由决定
<div ng-view></div>
渲染视图须要在页面初始化以前知道路由配置.
使用congfig();
congfig();
在应用程序执行以前执行一个配置方法,在页面还未被渲染,能够将路由逻辑放入该方法中。
回调函数:
this -> window
默认参数是空的,须要将服务注入
// 配置 app.config(function ( $routeProvider ) { $routeProvider.when('/', { // 模板 // template: '<div>嘻嘻哈哈</div>', templateUrl: 'a.html', // 控制器 controller: function ( $scope ) { console.log( $scope ); $scope.style = { color: 'deeppink' } } });
$routeProvider
路由服务:
路由供给服务,提供一个when方法,供使用配置路由.
controller
在路由对象中,能够经过controller属性,为路由对象添加控制器,建立一个做用域,让模板可使用做用域中的变量。
template
配置模板字符串
templateUrl
配置外部模板
会发送异步请求
otherwise
重定义路由
配置两个路由以上,otherwise 才会有效果.
配置参数为 redirectTo 来重定向到不一样路由,值是定义过路径.
// app var app = angular.module('app', ['ngRoute']); // controller app.controller('routerCtrl', function ( $scope ) { $scope.shop = 'shopPage1'; }); // config app.config(function ( $routeProvider ) { // 配置首页 路由 $routeProvider.when('/', { template: '<h1>{{ index }}</h1>', controller: function ( $scope ) { $scope.index = 'indexPage'; } }) // 配置 shop 页面 路由 .when('/shop', { template: '<h1>{{ shop }}</h1>', controller: function ( $scope ) { // $scope.shop = 'shopPage'; } }) // 其它路由 重定义 到 / 目录中 .otherwise({ redirectTo: '/' }); });
路由参数
路由路径配置参数(参数名前须要加:冒号)
将获取路由参数服务注入控制器中($routeParams注入控制器中).
app.config(function ( $routeProvider ) { // 配置参数 $routeProvider.when('/shop/:pageNum/:type', { template: '<h1>{{ shop }}</h1>', // 参数注入 controller: function ( $scope, $routeParams ) { $scope.shop = 'shopPage'; console.log( $routeParams ); } }); });
路由时间
路由时间一般定义须要监听该事件的控制器中,在全局做用域下监听,经过对做用域$on()方法监听路由事件。
例如:$routeChangeSuccess
监听路由改变成功
参数1: 表示事件对象
参数2:表示当前路由对象
参数3:表示前一个路由(若是当前没有前一个路由对象,所以参数会是undefined)
app.run(function ( $rootScope ) { $rootScope.$on('$routeChangeSuccess', function ( ev, routeObj, preRouteObj ) { }); });
$location
管理地址栏状态信息,包括query,path
path(): 改变路由中的path.
读:$location.path();
设:$loction.path(arg);
app.run(function ( $rootScope, $location ) { $rootScope.$on('$routeChangeSuccess', function ( ev, routeObj, preRouteObj ) { // var q = $location.path(); // 读 $location.path('/xixi'); // 设置 }); });
ngRoute: 每一个页面对应一个地址(path), 须要渲染那个页面,就须要配置路由.
uiRouter: 引入state(状态)概念,若是哪一个页面若是显示,渲染出对应的页面,渲染以后会有一种状态,能够将该状态记录,配置路由
ui-view
在ui-router 中使用的指令ui
<div ui-view=""></div>
$stateProvider
参数注入到config()来定义状态
app.config(function ( $stateProvider ) {});
state();
定义状态
参数1:状态名称
参数2:配置参数
url: 状态页面的地址
tempate: 状态对应页面的模板
controller 定义状态对应页面的做用域
// 参数注入 ui.router var app = angular.module('app', ['ui.router']); // 配置路由 app.config(function ( $stateProvider ) { // $stateProvider 定义状态 console.log( $stateProvider ); $stateProvider.state('home', { // 配置 #/ url: '/', template: '<h1>{{ indexPage }}</h1>', controller: function ( $scope ) { $scope.indexPage = 'indexPage'; console.log( this,arguments ); } }) .state('shop', { url: '/shop', template: '<h1>{{ shopPage }}</h1>', controller: function ( $scope ) { $scope.shopPage = 'shopPage'; console.log( this,arguments ); } }) });
uiRouter路由参数规则
路由规则:
固定值:/key
可捕获的参数: /:key
限制字段类型: /{key:type} type: int,string
捕获query: ?queryNum&queryNum2
$stateProvider.state('shop', { // url: '/shop/xixi/is/100?form=10&to=20' url: '/shop/:value/is/{pageNum:int}?form&to', template: '<h1>{{ shopPage }}</h1>', controller: function ( $scope, $stateParams ) { console.log( $stateParams ); $scope.shopPage = 'shopPage'; } })
$urlRouterProvider
when(); 将参数1的路由路径重定向到参数2路由路径
otherwise(); 匹配不存在的路由,跳转到定义过的路由.
// 配置 不存在路由 $urlRouterProvider.when('', '/').otherwise('/error');
views 多视图
ui-router 能够渲染页面中的多个视图,经过为页面中ui-view指令添加名称,多个视图渲染须要在config() 配置。
<div> <div class="left" ui-view="leftView"></div> <div class="content" ui-view="contentView"></div> <div class="right" ui-view="rightView"></div> </div>
app.config(function ( $stateProvider, $urlRouterProvider ) { $stateProvider.state('home', { url: '/', views: { leftView: { template: '<h1>leftView</h1>' }, rightView: { template: '<h1>rightView</h1>' }, contentView: { template: '<h1>contentView {{ msg }}</h1>', controller: function ( $scope ) { $scope.msg = '中间模块' } } } });
view 嵌套
在 ui-reouter 中视图是能够嵌套。
在state() 定义状态名称的时候添加命名空间。
路由须要有顺序,定义在父路由的后边。
注意:父视图须要添加动态视图ui-view
多视图不能与嵌套视图同时使用
匹配主页,定义路径不须要添加 '/shop', 直接 'shop';便可.
app.config(function ( $stateProvider, $urlRouterProvider ) { $stateProvider.state('home', { url: '/', template: '<div>index<div ui-view></div></div>' }) .state('home.shop', { url: 'shop', template: '<h1>shopPage</h1>' }); $urlRouterProvider.when('','/'); });
路由事件
添加在全局做用域$rootScope 下检测路径变化
事件名以state开头
参数1: 事件对象
参数2: 当前路由对象
参数3: 当前路由参数对象
参数4: 前一个路由对象
参数5: 前一个路由参数对象
app.run(function ( $rootScope ) { $rootScope.$on('$stateChangeSuccess', function ( ev, routeObj, routeParamsObj, preRouteObj, preRouteParamsObj ) { console.log( this,arguments ); }) });