AngularJs
angular数据双向绑定的框架 提供数据绑定,DOM指令。angular,定义了一套规则,开发中就必须遵守规则,这套规则为项目提供了一套解决方案。
基本概念启动/引导启动/引导 (Bootstrap) 属性型指令属性型指令 (Attribute Directive) 组件组件(Component) 在类中定义组件的应用逻辑 ( 它被用来为视图提供支持 ),组件通过一些由属性和方法组成的 API 与视图交互。 组件是Angular系统中最重要的基本构造核心之一。
数据绑定数据绑定(Data Binding)
在双向数据绑定中,数据的属性值会从具有属性绑定的组件传到输入框。通过事件绑定,用户的修改数据传回到组件,把属性值设置为最新的值。 Anuglar 在每一个JS事件周期中一次性处理所有的数据绑定,它会从组件树的根部开始,用深度优先的方式! (数据绑定在模板与对应组件的交互中起到了重要作用)
组件从技术角度上看就是一个指令。组件位置很独特,并在Angular中位于中心地位。 插值表达式
单向绑定 (ng-bind) 和双向绑定(ng-model) ng-bind 单项数据绑定 ($scope -> view) 用于数据显示,简写形式 ng-model 双向数据绑定 ($scope -> view and view -> $scope) ,用户绑定值会变化的表单元素等. 每次绑定一个东西到 view 上时 AngularJS 就会往 $watch 队列里插入一条 $watch,用来检测它监视的 model 里是否有变化的东西。 当浏览器接收到可以被 angular context 处理的事件时,$digest 循环就会触发。$digest 会遍历所有的 $watch 。 一次更新数据操作,至少会触发两次$digest() 循环,$gigest循环的次数达到了10次(超过10次后抛出一个异常,为了防止无限循环) 依赖注入依赖注入(Dependency Injection) 需要依赖的原因:没法控制这实例背后隐藏的依赖。 当不能控制依赖时,类就会变得难以测试。 按需注入,需要才注入。 依赖注入即是设计模式,同时又是一种机制:当应用程序的一些组件需要另外一些组件的时候,使用依赖注入机制来创建被请求的部件并将其注入到发出请求的组件中。 提供类的新势力的一种方式,负责处理好累所需的全部依赖。大多数依赖都是服务。Angualr使用依赖注入提供所需的组件以及组件所需的服务。
angular构建应用程序时:定义许多精简的小部件,每个小部件只做一件事,并且做好它,然后在运行期把这写精简小部件装配在一起组成应用程序。 依赖注入的核心是:注入器(Injector),这个注入器根据需要返回被依赖的部件。injector.get(token) 方法返回与token(令牌)参数相关的依赖部件。
令牌是一个Angular中类型.绝大多数类方法都接受类名或字符串。Angular会把这些类名称和字符串转换成令牌。当调用injector.get(Foo)时,注入器返回用Foo类生成的令牌所对应的依赖值,该依赖值通常是Foo 类的实例。 注入器(Injector)维护一个令牌与相应依赖值的对照表(map)。如果注入器不能找到一个令牌对应的依赖值,它就会使用提供商(Provider) 来创建一个依赖值. 提供商是创建依赖实例的“菜谱”之一,这个实例会与一个特定的令牌关联起来。 只有当注入器内部的提供商注册表中存在于令牌对应的提供商时,注入器才能为这个令牌创建一个依赖值。 angular会为每个注入器注册很多angular内建提供商。
指令指令(Directive) 指令包括的类别:
注入器注入器(Injector) 注入器是一个维护服务实例的容器,存放着以前创建的实例。 插值表达式插值表达式(Interolation) 属性数据绑定的形式:位于双大括号中的模板表达式会被渲染成文本。 模块模块(Module)
模块:具有单一用途的内聚代码块 一个模块加载器来按需加载模块并解析模块的依赖关系。 模块库
有些模块是其它模块的库 管道管道(Pipe) 管道是一个函数 提供商提供商(Provider) 服务服务是一个类,具体实现一件事情,具有专注,良好定义的用途。
结构型指令添加,删除或操作元素和其各级子元素来塑造或重塑HTML布局的指令。 例如:ngIf 模板模板(Template)
装饰器装饰器 (Decorator | Decoration) 装饰器是一个 函数,这个函数将元数据添加到类,类成员(属性,方法)和函数上。 angular 使用自身一套装饰器来实现应用程序各个部分之间的相互操作。 基础指令ng-app应用程序的指令,一个程序中必须要有该指令 <body ng-app></body> ng-model数据绑定的指令,将数据绑定到应用程序中 <input type="text" ng-model="msg" /> ng-bind绑定数据,它的简写方式直接在元素中{{key}} <div>{{ msg }}</div> 当页面加载完毕,angularjs启动起来,首先回去页面中寻找ng-app指令,找到后初始化应用程序。 ng-init表示初始化应用程序中的变量,多个变量用; 注意定义多个变量不能用逗号,只能用分号; <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> module通过angular.module方法 var app = angular.module('app',[]); controller控制器定义控制器 定义控制器 angular参数注入:想用什么东西就在参数中注入。
<div ng-controller="msg"></div> // 控制器 app.controller('msg',function ( $scope ) { console.log( this ); console.log( arguments ); }); 控制器$scope$scope: 用来实现数据与视图的连接,在$scope上定义的数据,可以用视图在上,那么视图上绑定的数据可以在$scope上也能获取到 $scope 是通过原型式继承实现, 子作用域会继承父作用域中的变量,但是可以为子作用域添加变量还重写符作用域中的变量。 scope特点
scope生命周期
在创建控制器或指令时,angularjs会用$onjector创建一个新的作用域,并在这个新建的控制器或指令时把作用域传进去
scope对象会附加或链接到视图。这些作用域将会注册到 angular上下文中发生变化时需要运行的函数
事件循环执行时,顶级的$rootScoep和每个子作用域都执行自己的脏值检查。某个监控函数监控变化,检测到变化后,$scope会触发指定的回调函数。
当scope在视图中不再需要时,会清晰和销毁自己。 eventsng-eventsName 执行的作用域是$scope,当前的作用域 <button ng-click="clickBtn('info',$event)" ng-bind="red"></button> // 事件 $scope.clickBtn = function ( msg,ev ) { } 显隐ng-show 表示显示元素指令 <span ng-show="isShow">1</span> <span ng-hide="isShow">2</span> 表达式插值和数据的过程中可以应用表达式 <div>{{'面积是:' + width * height}}</div> <div>{{ msg.toUpperCase() }}</div> 过滤器用来对绑定数据显示时候处理 内置过滤器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','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> 字符串大小写 <div>{{ msg | uppercase }}</div> <div>{{ msg | lowercase }}</div> <div>{{ msg.toLowerCase() }}</div> number过滤器 <div>{{ num | number }}</div> <div>{{ num | number : 4 }}</div> orderBy <div>{{ color | orderBy : '' : true }}</div> <div>{{ color | orderBy }}</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,$1 ) { return $1.toUpperCase(); }); } return ''; } }); 表单验证当对表单元素form添加name属性时候,angular会自动将该属性的值添加到作用域中,并且该属性具有表单验证的属性. 具有 $dirty 表单是否被用户输入过,输入过,值为true,没有输入过值为false $valid 属性值为true时,所有表单元素必须$valid都是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> run-$rootScope获取app并执行(程序入口指令会提供一个run方法),通常会在该方法中访问根作用域,该方法接收一个函数作为参数, 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指令ng-disabled <input type="text" ng-disabled="isable" name="" /> ng-readonly <input type="text" ng-readonly="isable" name="" id="" value="" /> ng-checked <input type="checkbox" ng-checked="isabel" name="" id="" value="" /> ng-change <input type="text" ng-model="msg" ng-change="change()" name="" /> app.controller('inp',function ( $scope ) { $scope.change = function () { alert($scope.msg); } }); ng-submit <form name="forms" ng-submit="submit()"> <input type="text" name="" ng-model="msg" id="" value="" /> <input type="submit" value="提交"/> </form> ng-src <img ng-src="{{imgSrc}}" /> ng-href <a ng-href="{{Url}}">跳转</a> ng-class <div ng-class="{red: ngClassInfo>4,green: ngClassInfo <=4 }">{{ ngClassInfo }}</div> ng-style <div ng-style="{background: 'tan',width: '100px',height: '100px'}"></div> ng-if <div ng-if="isable">222222222211</div> <div ng-if="!isable">222222222222</div> ng-switch <!--需要将分支判断的元素放入 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 <ul> <li ng-repeat="item in colors" ng-class="{red: $odd}">{{ item }} --- {{'索引值:'+$index}} --- {{ $middle }}</li> </ul> ng-include <div ng-controller="aMsg"> <div ng-include="'a.html'"></div> </div> // 数据传输 var aMsgApp = app.controller('aMsg',function ( $scope ) { $scope.msg = '载入成功'; });
自定义指令directive();参数1: 指令的名称 规则:
返回对象restrict: 自定义指令的类型 template: 传递的是模板字符串 templateUrl: 模板文件的路径 replace: false controller // 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,$attrs ); } } }); scope directive返回对象中的scope和controller app.directive('myCutom',function () { return { restrict: 'E',template: '<h1>{{ msg }} -- {{ title }}</h1>',// scope: {},// scope: true,scope: false controller: function ( $scope,$attrs ) { $scope.title = 'aaaa'; $scope.msg = 'xixixi'; } } }); @修饰符 <my-custom my-title="{{title}}"></my-custom> app.directive('myCutom',scope: { // 告知 自定义指令 不需要从 自己的作用域中寻找 变量 title: '@myTitle' },$attrs ) { $scope.title = 'aaaa'; $scope.msg = 'xixixi'; } } }); =修饰符 作用:自定义指令作用域中变量与父作用域的双向绑定过程. template,中的数据和 父级的作用域$scope,数据绑定 tempalte: '<h1>{{title}}</h1>', app.controller('main',function ( $scope ) { $scope.title = ''; }); link 操作自定义指令的DOM link的函数 // 操作自定义指令元素 // @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指向的是指令描述对象. <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,attrs ) { // this -> window var color = attrs.color; jqlite.css('color',color); } } } }); </script> transclude 它告诉自定义指令,要将自定义元素中未知的元素内容插入到已知模板具有ng-transclude指令所在的元素中(添加自定义指令元素中的未知元素) 告知自定义指令,要将自定义中未知的元素内容插入到已知模板。 现象:模板标签会包裹自定义标签内的内容. app.directive('myDirective',template: '<div ng-transclude></div>',transclude: true } }); require 自定义指令引用其它指令,作为link()方法的第四个参数. require: 'ngModel' // 自定义指令 app.directive('myDirective',function () { // 返回一个描述指令对象 return { restrict: 'A',// 引入其它指令 require: 'ngModel',link: function ( scope,attrs,ngModel ) { // $watch 检测某个值 发生改变,触发某个函数 // 当 ngModel 值发生改变, 触发函数 scope.$watch(attrs.ngModel,function () { console.log(ngModel.$viewValue); }); } } }); 服务对一些方法的封装,复用方法更为简便。例如:消息系统,作为消息服务.
内置服务$timeout app.controller('main',function ($scope,$timeout) { $timeout(function () { console.log(this); console.log(arguments); },2000); }); $interval app.controller('main',$interval) { // 定义一个时间 $scope.date = new Date(); $interval(function () { // 重新定义日期 $scope.date = new Date(); },1000); }); $http 配置参数: POST请求: // $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 // 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对象 自定服务需要各种服务以支持各种功能,也可以手动开启或关闭某些服务以达到相应的功能. factory() var app = angular.module('app',[]); // 其它控制器使用服务 app.controller('facotryCtrl',function ( $scope,news ) { $scope.msg = news.data; }); // factory 定义 服务 app.factory('news',function () { return { data: '嘻嘻哈哈' } }); service 面向对象创建服务 // 使用 service 自定义服务 app.service('data',function () { this.title = '嘻嘻哈哈'; }); 路由使用组件配合使用: 路由: ngRoute需要在程序入口处引入,添加到依赖集合中 angualr.module('app',['ngRoute']); ng-view 动态渲染的视图,视图如何渲染根据路由决定 <div ng-view></div> 渲染视图需要在页面初始化之前知道路由配置. congfig(); // 配置 app.config(function ( $routeProvider ) { $routeProvider.when('/',{ // 模板 // template: '<div>嘻嘻哈哈</div>',templateUrl: 'a.html',// 控制器 controller: function ( $scope ) { console.log( $scope ); $scope.style = { color: 'deeppink' } } }); $routeProvider controller template templateUrl otherwise // 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: '/' }); }); 路由参数 路由路径配置参数(参数名前需要加:冒号) app.config(function ( $routeProvider ) { // 配置参数 $routeProvider.when('/shop/:pageNum/:type',// 参数注入 controller: function ( $scope,$routeParams ) { $scope.shop = 'shopPage'; console.log( $routeParams ); } }); }); 路由时间 app.run(function ( $rootScope ) { $rootScope.$on('$routeChangeSuccess',function ( ev,routeObj,preRouteObj ) { }); }); $location app.run(function ( $rootScope,$location ) { $rootScope.$on('$routeChangeSuccess',preRouteObj ) { // var q = $location.path(); // 读 $location.path('/xixi'); // 设置 }); }); ui-routerngRoute: 每个页面对应一个地址(path),需要渲染那个页面,就需要配置路由. ui-view 在ui-router 中使用的指令ui <div ui-view=""></div> $stateProvider app.config(function ( $stateProvider ) {}); state(); // 参数注入 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路由参数规则
$stateProvider.state('shop',{ // url: '/shop/xixi/is/100?form=10&to=20' url: '/shop/:value/is/{pageNum:int}?form&to',$stateParams ) { console.log( $stateParams ); $scope.shopPage = 'shopPage'; } }) $urlRouterProvider // 配置 不存在路由 $urlRouterProvider.when('','/').otherwise('/error'); views 多视图 <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 嵌套 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('','/'); }); 路由事件 app.run(function ( $rootScope ) { $rootScope.$on('$stateChangeSuccess',routeParamsObj,preRouteObj,preRouteParamsObj ) { console.log( this,arguments ); }) }); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |