angularjs介绍
由来
AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购。是一款优秀的前端JS框架,已经被用于Google的多款产品当中。AngularJS有着诸多特性,最为核心的是:MVVM、模块化、自动化双向数据绑定、语义化标签、依赖注入,等等。———百度百科
<html ng-app ="hello"> <body> <div ng-controller = "TextController"> <p >{{someText}}</p> </div> <div ng-controller ="InputCtrl"> <input type="text" ng-model='user.name' /> <input type="text" ng-model='user.last' /> <span>{{user}}</span> </div> <script type="text/javascript" src="script/angular.min.js"></script> <script type="text/javascript"> angular.module('hello', []).controller('TextController', function($scope) { $scope.someText = "Hello World"; }); function InputCtrl($scope) { $scope.user = { name: 'guest', last: 'visitor' }; } </script> </body> </html>
angularjs
常用指令
ng-app、 ng-init 、 ng-model 、 ng-repeat、ng-disabled、ng-show、ng-hide
事件指令
ng-click、ng-dbl-click、ng-mousedown、ng-mouseup、ng-mouseenter、ng-mouseleave、ng-mousemove、ng-mouseover、ng-keydown、ng-keyup、ng-keypress、ng-change
ng-repeat
<html> <head> <title>repeat</title> <style type="text/css"> .selected{background:lightgreen;} </style> <script type="text/javascript" src="../script/angular.min.js"></script> </head> <body ng-app="repeatApp" ng-controller="repeatController"> <table> <tr> <td>Type</td> <td>Price</td> <td>Count</td> <td>totalPrice</td> </tr> <tr ng-repeat="item in items" ng-click="selecItem($index)" ng-class="{selected:$index==selectRow}"> <td>{{item.type}}:</td> <td>{{item.price | currency}}</td> <td>{{item.count}}</td>< td>{{item.total}}</td> </tr> </table> </body> <script type="text/javascript"> var arr = [{ type: "apple", price: 6.3, count: 10 }, { type: "orange", price: 8.1, count: 5 }, { type: "egg", price: 123, count: 6 }]; var a = angular.module("repeatApp", []); function repeatController($scope) { $scope.items = arr; angular.forEach($scope.items, function(value, key) { value.total = value.price * value.count; }); $scope.selecItem = function(row) { $scope.selectRow = row; } window.scope = $scope; } </script> </html>
内置服务
$http、$ templateCache 、$log、$location 、$cookieStore、$animate、$q
内置方法
bind,bootstrap,copy,element,equals,extend,forEach,fromJson,identity,injector,isArray,isDate,isDefined,isElement,isFunction,isNumber,isObject,isString,isUndefined,lowercase,module,noop,toJson,uppercase
demo
http:
伪代码:
1 $http.get('url',{params:{id:5} 2 }).success(function(data,status,headers,config){ 3 //success callback 4 }).error(function(data,status,headers,config){ 5 //error callback 6 })
get/head/post/delete/put/JSONP
$http({
method: string,
url: string,
param: obj,
data: string or object,
headers: object,
transformRequest: function transform(data, headersGetter) or an array of functions,
transformRespones: function transform(data, headersGetter) or an array of functions,
cache: boolean or Cache object,
timeout: number,
withCredentials: boolean
})
demo:
<html> <head> <title>Time</title> <style type="text/css"> .selected{background:lightgreen;} </style> <script type="text/javascript" src="../script/angular.min.js"></script> </head> <body ng-app="myApp" ng-controller="repeatController"> <p>date:{{date}}</p> <p>time:{{time}}</p> </body> <script type="text/javascript"> angular.module("myApp", []); function repeatController($scope, $http) { $http.jsonp("http://service.100bt.com/PubTimeNow.action?callback=JSON_CALLBACK") .success(function(data, status, headers, config) { $scope.date = data.date; $scope.time = data.time; console.log(data, status, headers(), config); }) } </script> </html>
/*
log();
Write a log message
<html> <head> <title>log</title> <script type="text/javascript" src="../script/angular.min.js"></script> </head> <body ng-app="myApp" ng-controller="myController"> </body> <script type="text/javascript"> var myApp = angular.module('myApp', []); myApp.controller("myController",function($scope,$log){ $log.log("xxx"); })
info();
Write an information message
warn();
Write a warning message
error();
Write an error message
debug();
Write a debug message
*/
</script>
</html>
templateCache
<html> <head> <title>templateCache</title> <script type="text/javascript" src="../script/angular.min.js"></script> </head> <body ng-app="myApp" ng-controller="control"> <div ng-include=" 'templateId.html' "></div> </body> <script type="text/javascript"> var myApp = angular.module('myApp', []); /* myApp.run(function($templateCache) { $templateCache.put('templateId.html', 'This is the content of the template'); $templateCache.get('templateId.html'); }).controller("control",function(){}); */ myApp.controller("control", function($scope, $templateCache, $log) { $templateCache.put('templateId.html'); $templateCache.get('templateId.html'); }) </script> </html>
templateId.html
<div>xxxxxxxxxxxx</div>
$watch
$watch(watchFn,watchAction,deepWatch)
watchFn: 带有angular表达式或者函数字符串,返回被监控模型的当前值。会执行多次
watchAction: 一个函数或者表达式,watchFn发生变动时调用,返回watchFn的新旧两个值,和作用域的引用。function(newValue,oldValue,scope)
deepWatch: 设置了true则会去检查被监控对象的每个属性是否发生了变化。如果要监控数组中的元素,或者对象上的全部属性,而不是一个简单的值,就可以使用这个参数。
<html ng-app ="storeData"> <body> <div ng-controller ="InputCtrl"> <div><button ng-click="toggleShow()">toggleData</button><input type="text" ng-model='newData' ng-keypress="createOnEnter($event)" placeholder="What needs to be done?" /></div> <ul ng-show="showMe"> <li ng-repeat="item in storeData track by $index" ng-mouseover="showBtn($index)">{{item}}<button ng-show="$index==selectRow" ng-click="remove($index)">removeThis</button></li> </ul> <div>{{count}}ItemLeft</div> </div> <script type="text/javascript" src="script/angular.min.js"></script> <script type="text/javascript"> var aaa = angular.module("storeData", []) .controller("InputCtrl", function($scope) { $scope.storeData = []; $scope.count; $scope.showMe = true; var activeData = [], allData = [], removeData = [], count = 0; $scope.toggleShow = function() { $scope.showMe = !$scope.showMe; }; $scope.showBtn = function($index) { $scope.selectRow = $index; }; $scope.createOnEnter = function($event) { if ($event.keyCode == 13) { allData.push($scope.newData); activeData.push($scope.newData); $scope.newData = ""; } } $scope.remove = function(index) { var d = allData.splice(index, 1); removeData.push(d); } $scope.storeData = allData; $scope.count = count; function calculateCount(newValue, oldValue, scope) { console.log(1); console.log(newValue, oldValue); $scope.count = newValue.length; } $scope.$watch(function() { return $scope.storeData }, calculateCount, true); }) </script> </body> </html>
Module
controller
第一种:通过方法名声明依赖
function mycontroller($scroper,$time){};
第二种:声明一个数组,依赖列表放前部,注入目标数组放最后
var mycontroller = [‘$scope’,’$time’,function($scope,$time){}];
第三种:通过inject属性声明依赖列表
var mycontroller = function($scope,$time){};
mycontroller.$inject = [‘$scope’,’$time’];
Filter
{{expression | filterName:paramter1:…paramterN}}
内置:
currency、date、number/uppercase
<html ng-app ="filterModule"> <title>系统filter</title> <style type="text/css"> .selected{background:lightgreen;} </style> <body> <div ng-controller = "priceController"> <!--JSON--> {{ {foo: "bar", baz: 23} | json }} <!--货币--> <p>{{250 | currency}}</p> <p>{{ 250 | currency:"RMB ¥ " }} </p> <!--日期--> <p>{{ 1427109979466 | date }} </p> <p>{{ 1427109979466 | date:"MM/dd/yyyy @ h:mma" }} </p> <p>{{ 1427109979466 | date:"yyyy-MM-dd hh:mm:ss" }} </p> <!--数字--> <p>{{ 1.234567 | number:1 }} </p> <p>{{ 1234567 | number }}</p> <!--filter查找--> {{ [{"age": 20,"id": 10,"name": "iphone"}, {"age": 12,"id": 11,"name": "sunm xing"}, {"age": 44,"id": 12,"name": "test abc"} ] | filter:'s'}} <!--limitTo截取--> <p>{{ "This is angularjs" | limitTo:7 }} </p> <p>{{ "This is angularjs" | limitTo:-2 }}</p> <p>{{[1,2,3] | limitTo:1 }}</p> <!--orderBy对像排序--> {{ [{"age": 20,"id": 10,"name": "iphone"}, {"age": 12,"id": 11,"name": "sunm xing"}, {"age": 44,"id": 12,"name": "test abc"} ] | orderBy:'id':true }} //根据id降序排 {{ [{"age": 20,"id": 10,"name": "iphone"}, {"age": 12,"id": 11,"name": "sunm xing"}, {"age": 44,"id": 12,"name": "test abc"} ] | orderBy:'id' }} //根据id升序排 </div> <script type="text/javascript" src="../script/angular.min.js"></script> <script type="text/javascript"> angular.module('filterModule',[]) .controller('priceController', function($scope) { }); </script> </body> </html>
自定义:
<html> <head> <title>自定义filter</title> <script type="text/javascript" src="../script/angular.min.js"></script> </head> <body ng-app="filterModule" ng-controller="filterController"> <h1>{{pageHeading | titleCase }}</h1> </body> <script type="text/javascript"> angular.module('filterModule', []) .filter('titleCase', function() { return function(text) { var words = text.split(' '); for (var i = 0, len = words.length; i < len; i++) { words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1); } return words.join(' '); } }) .controller("filterController", function($scope) { $scope.pageHeading = "this is filter"; }) </script> </html>
factory、service 、provider
service(name, constructor)
factory(name,$getFunction())
provider(name,Objector constructor())
<html> <head> <title>demo</title> <script type="text/javascript" src="../script/angular.min.js"></script> </head> <body ng-app="myApp" ng-controller="myController"> <p>facetorytest:{{factorytest}}</p> <p>servicetest:{{servicetest}}</p> <p>providertest:{{providertest}}</p> </body> <script type="text/javascript"> var myApp = angular.module("myApp", []); myApp.factory("factorytest", function() { var test = {}; test.name = "factorytest"; return test; }) myApp.service("servicetest", function() { this.name = "servicetest"; }) myApp.provider("providertest", function() { this.$get = function() { return "providertest"; } }) myApp.controller("myController", function($scope, factorytest, servicetest, providertest) { $scope.factorytest = factorytest.name; $scope.servicetest = servicetest.name; $scope.providertest = providertest; }) </script> </html>
directive
myModule.directive(‘directive’,functionfactory(injectables){ var directiveDefinitionObject ={ } return directiveDefinitionObject ; })
compile和link
Angular初始化:
加载脚本
编译阶段:(遍历dom,根据指令(template、replace)转换dom结构),存在compile函数则调用 ,scope在链接阶段才会被绑定到元素上,因此compile阶段操作scope会报错;
链接阶段: 为了让视图成为动态,对每条指令运行一个link函数;
对于同一个指令的多个实例,compile只会执行一次;而link对于指令的每个实例都会执行一次;
伪代码:
var myModule = angular.module(...);
myModule.directive('namespacesDirectiveName',function factory(injectables){
var directiveDefinitionObject = {
restrict:string,/* E 元素 A 属性 C 样式类 M 注释 */
priority:number,
tamplate:string,
tamplateUrl:string,
replace:bool,
transclude:bool, /*把当前指令中的子节点移动到模板的内部*/
scope:bool or object,
controller:function controllerConstructor($scope,$element,$attrs,$transclude){
...
},
require:string,
link:function postLink(scope,iElement,iAttrs){
...
},/*实例元素 Instance*/
compile:function compile(tElement,tAttrs,transclude){
return {
pre:function preLink(scope,iElement,iAttrs,controller){...},
post:function preLink(scope,iElement,iAttrs,controller){...}
}
}/*模板元素 tamplate*/
}
return directiveDefinitionObject;
})
var myModule = angular.module(...); myModule.directive('namespacesDirectiveName', function factory(injectables) { var directiveDefinitionObject = { restrict: string, /* E 元素 A 属性 C 样式类 M 注释 */ priority: number, tamplate: string, tamplateUrl: string, replace: bool, transclude: bool, /*把当前指令中的子节点移动到模板的内部*/ scope: bool or object, controller: function controllerConstructor($scope, $element, $attrs, $transclude) { ... }, require: string, link: function postLink(scope, iElement, iAttrs) { ... }, /*实例元素 Instance*/ compile: function compile(tElement, tAttrs, transclude) { return { pre: function preLink(scope, iElement, iAttrs, controller) {... }, post: function preLink(scope, iElement, iAttrs, controller) {... } } } /*模板元素 tamplate*/ } return directiveDefinitionObject; })
demo1:
<body ng-app="app"> <hello></hello> </body> <script type="text/javascript"> var appModule = angular.module('app', []); appModule.directive('hello', function() { return { restrict: 'E', template: '<div >Hi there</div>', replace: false }; }); </script>
/*
restrict:
E 元素
A 属性
C 样式类
M 注释
*/
</script>
demo2:
<body ng-app="app"> <hello> <br/> <span>原始的内容,</span><br/> <span>还会在这里。</span> </hello> <hello> </hello> </body> <script type="text/javascript"> var appModule = angular.module('app', []); appModule.directive('hello', function() { return { restrict: 'E', template: '<div>替换内容 <span ng-transclude></span></div>', transclude: true }; }); </script>
demo3:
<body ng-app="app"> <hello> <span>原始的内容,</span> </hello> <hello> </hello> </body> <script type="text/javascript"> var appModule = angular.module('app', []); /* appModule.run(function($templateCache){ $templateCache.put('templateId.html','<div>templateUrl</div>') })*/ appModule.directive('hello', function() { return { restrict: 'E', templateUrl: 'templateId.html', transclude: true }; }); </script>
demo4:
<html> <head> <title></title> <script type="text/javascript" src="../script/angular.min.js"></script> <style type="text/css"> .expander { border: 1px solid red; width: 250px; } .expander>.title { color: white; padding: 1em 3em; cursor: pointer; } .expander>.body { padding: 1em 3em; } .close{display:none;} </style> </head> <body ng-app="app" ng-controller="SomeController"> <expander class="expander" aa-a="title" expander-text="text"> {{text}} </expander> <!--<input type="text" ng-model="title"/>--> </body> <script type="text/javascript"> var appModule = angular.module('app', []); appModule.directive('expander', function() { return { restrict: 'E', replace: true, transclude: true, scope: { Title: '=aaA' }, /*创建scope的局部属性,与父scope中的expander-title绑定*/ template: '<div>' + '<div class="title" ng-click="toggle()">{{Title}}</div>' + '<div class="body" ng-transclude></div>' + '</div>', link: function(scope, element, attrs) { console.log(element) var titleElement = angular.element(element.children().eq(0)); var bodyElement = angular.element(element.children().eq(1)); titleElement.bind('click', toggle); function toggle() { bodyElement.toggleClass('close'); } } }; }); appModule.controller("SomeController", function($scope) { $scope.title = "Click me to expand"; $scope.text = 'Toggle Information'; }) </script> </html>
templateId.html
<div>xxxxxxxxxxxx</div>
route
通过$routeRrovider服务上的函数来创建路由,把需要创建的路由当成配置块传给模块即可。
var someModule = angular.module('someModule', [..moduleDependencies..]) someModule.config(function($routerProvider) { $routerProvider. when('url', { controller, templateUrl: '/path/to/template' }). when(...other mappings for you app...). otherwise(...what to do if nothing else matches...) })
index.html
<html ng-app='AMail'> <head> <script type="text/javascript" src="http://angular.100bt.com/script/angular.min.js"></script> <script type="text/javascript" src="http://angular.100bt.com/angular-route.js"></script> <script type="text/javascript" src="script/controllers.js"></script> </head> <body> <h1>A-Mail</h1> <div ng-view></div> </body> </html>
list.html
<table> <tr> <td><strong>Sender</strong></td> <td><strong>Subject</strong></td> <td><strong>Date</strong></td> </tr> <tr ng-repeat='message in messages'> <td>{{message.sender}}</td> <td><a href="#/view/{{message.id}}">{{message.subject}}</a></td> <td>{{message.date}}</td> </tr> </table>
detail.html
<div><strong>Subject:</strong>{{message.subject}}</div> <div><strong>Sender:</strong>{{message.sender}}</div> <div><strong>Date:</strong>{{message.date}}</div> <div> <strong>To:</strong> <span ng-repeat='recipient in message.recipients'>{{recipient}}</span> </div> <div>{{message.message}}</div> <a href="#/">Back to message list</a>
controllers.js
var aMailServices = angular.module('AMail', ["ngRoute"]) function emailRouteConfig($routeProvider) { $routeProvider.when('/', { controller: ListController, templateUrl: 'list.html' }).when('/view/:id', { controller: DetailController, templateUrl: 'detail.html' }).otherwise({ redirectTo: '/' }); } aMailServices.config(['$routeProvider', emailRouteConfig]); messages = [{ id: 0, sender: '0@qq.com', subject: '0mail', date: "0:00:00", recipients: ['00.qq.com'], message: 'this is 0 mail' }, { id: 1, sender: '1@qq.com', subject: '1mail', date: "1:00:00", recipients: ['11.qq.com'], message: 'this is 1 mail' }, { id: 2, sender: '2@qq.com', subject: '2mail', date: "2:00:00", recipients: ['22.qq.com'], message: 'this is 2 mail' }] function ListController($scope, $routeParams) { $scope.messages = messages; } function DetailController($scope, $routeParams) { $scope.message = messages[$routeParams.id]; }