angular
作者:武超敏
邮箱:[email protected]
更改历史
* 2018-1-27 高天阳 整理文档 补充$log
* 2018-1-23 武超敏 增加$q内容
* 2017-9-17 张飞 添加参考链接
* 2017-6-1 杨丽 初始化文档
1 历史、现状和发展
1.1 历史
AngularJS最初由Misko Hevery和Adam Abrons于2009年开发,后来成为了Google公司的项目。
AngularJS弥补了HTML在构建应用方面的不足,其通过使用标识符(directives)结构,来扩展Web应用中的HTML词汇,
使开发者可以使用HTML来声明动态内容,从而使得Web开发和测试工作变得更加容易。
1.2 简介
AngularJS是一个JavaScript框架。它可通过 <script>
标签添加到HTML页面。
AngularJS通过指令扩展了HTML,且通过表达式绑定数据到HTML。
1.3 特点
AngularJS有着诸多特性,最为核心的是:MVVM、模块化、自动化双向数据绑定、语义化标签、依赖注入等等。
2 安装和使用
2.1 安装angular
bower install --save-dev angular
2.2 常用的指令
- mg-app
- ng-model
- ng-controller
- ng-if
- ng-show
- ng-hide
- ng-repeat
2.3 服务
服务是一个对象或函数,对外提供特定的功能。
内建服务:
- $location是对原生Javascript中location对象属性和方法的封装。
- $timeout&$interval对原生Javascript中的setTimeout和setInterval进行了封装。
- $filter在控制器中格式化数据。
- $log打印调试信息
- $http用于向服务端发起异步请求。
- 同时还支持多种快捷方式如$http.get()、$http.post()、$http.jsonp。
angular提供了3种方法来创建并注册我们自己的service
- Factory,
- Service,
- Provider
例子:
value 传递值
let app = angular.module("app",[]);
app.value("name","yide");
app.controller("myController",function($scope,name,){
$scope.title = name;
})
service (new 实例化)
angular.module("app").service("ydserve",function(){
this.name = "我是一个服务层";
});
factory (执行实例化)
angular.module("app").factory("util",function(){
return {
sum:function(number1,number2){
return number1 + number2;
}
};
});
provider
(是唯一一种你可以传进 .config() 函数的 service。当你想要在 service 对象启用之前,先进行模块范围的配置,那就应该用 provider)
tips:得到的是$get() 执行之后的数据
angular.module("app").provider("ydprovider",function(){
var _this = this;
this.name = "provideryd";
this.$get = function(){
return {name:_this.name}
}
});
2.4config
tips:注意名字后面加Provider
常用的$provide $compileProvider
angular.module("app").config(function(ydproviderProvider){
ydproviderProvider.name = "config";
});
2.5directive
priority
template
返回函数的时候函数里面要返回string (第二个形参看作元素)
返回对象
templateUrl
//缓存
angular.module("app").run(["$templateCache",function($templateCache){
$templateCache.put("yd.html","<div><h1>Hi 我是缓存的</h1></div>")
}]);
angular.module("app").directive("yd",function(){
let template = {
restrict:"E",
templateUrl:"yd.html",
replace:true
}
return template;
});
replace:是否替换原标签
transclude
restrict E(元素),A(属性),C(类),M(注释) (默认为A)
E(元素):<directiveName></directiveName>
A(属性):<div directiveName='expression'></div>
C(类): <div class='directiveName'></div>
M(注释):<--directive:directiveName expression-->
scope
false:同用一个scope
true:继承父scope如果自己有侧不用父scope的了
{}:不继承自己是单独的
隔离之后的双向绑定
{user: "="} 这个scope的user于父scope的user同步
{user: "@"} 父会改变它 它不会改变父
{fn: "&"} 拿到父的user这个函数
<div>Say:{{name}}<br>改变父scope的name:<input type="text" value="" ng-model="name"/></div>
<div>隔离scope:
<div yd name="{{name}}"></div>
</div>
<div>隔离scope(不使用父scope {{name}}): </div>
<div yd name="name"></div>
compile
link
2.6filter
angular.module("app").filter("reverse",function(){
return function(text,flag){
if(flag){
return text.split("").reverse().join("");
}
return text;
}
});
2.7$q
let promise = function(){
let deferred = $q.defer();
$http({
method:"GET",
url:"https://jsonplaceholder.typicode.com/users/"+Math.ceil(Math.random()*10)
}).then(function(data){
deferred.resolve(data);
},function(data){
deferred.reject(data)
});
return deferred.promise;//返回promise对象
}
var p1 = promise();
p1.then(function(na){
// alert(JSON.stringify(na));
},function(na){
// alert(JSON.stringify(na));
}).finally(function(){
// alert("反正我是最后执行的");
});
$q.all([promise(),promise(),p1]).then(function(result){
result.forEach(function(v,i){
console.log(v.data.name);
});
});
2.7.1$q.all的嵌套
函数1、2使用$q执行异步操作,对结果进行操作并执行函数5,
函数3、4使用$q执行异步操作,对结果进行操作并执行函数6,
函数5、6使用$q执行异步操作,对结果进行操作。
iWantResolve = true;//判断条件
function promise1() {
var deferred = $q.defer();
$timeout(function () {
if (iWantResolve) {
deferred.resolve("promise1 resolved");
} else {
deferred.reject("promise1 reject");
}
}, 500);
return deferred.promise;
}
function promise2() {
var deferred = $q.defer();
$timeout(function () {
if (iWantResolve) {
deferred.resolve("promise2 resolved");
} else {
deferred.reject("promise2 reject");
}
}, 500);
return deferred.promise;
}
function promise3() {
var deferred = $q.defer();
$timeout(function () {
if (iWantResolve) {
deferred.resolve("promise3 resolved");
} else {
deferred.reject("promise3 reject");
}
}, 500);
return deferred.promise;
}
function promise4() {
var deferred = $q.defer();
$timeout(function () {
if (iWantResolve) {
deferred.resolve("promise4 resolved");
} else {
deferred.reject("promise4 reject");
}
}, 500);
return deferred.promise;
}
function promise5() {
var deferred = $q.defer();
$timeout(function () {
if (iWantResolve) {
deferred.resolve("promise5 resolved");
} else {
deferred.reject("promise5 reject");
}
}, 500);
return deferred.promise;
}
function promise6() {
var deferred = $q.defer();
$timeout(function () {
if (iWantResolve) {
deferred.resolve("promise6 resolved");
} else {
deferred.reject("promise6 reject");
}
}, 500);
return deferred.promise;
}
var q = [];
var deferred5 = $q.defer();
var deferred6 = $q.defer();
$q.all([promise1(), promise2()])//执行promise1(), promise2()后,执行promise5()
.then(function (dataArr) {
console.log(dataArr);//对promise1(), promise2()的结果进行操作
promise5().then(function(data){
deferred5.resolve("promise5 resolved-----");
});
}, function (err) {
console.log("$q.all: ", err)
});
q.push(deferred5.promise);//将promise5()的结果push到q数组中
$q.all([promise3(), promise4()])//执行promise3(), promise4()后,执行promise6()
.then(function (dataArr) {
console.log(dataArr);//对promise3(), promise4()的结果进行操作
promise6().then(function(data){
deferred6.resolve("promise6 resolved-----");
});
}, function (err) {
console.log("$q.all: ", err)
});
q.push(deferred6.promise);//将promise6()的结果push到q数组中
$q.all(q)//运行q
.then(function (dataArr) {
console.log(dataArr);
}, function (err) {
console.log("$q.all: ", err)
});
2.7.2$q原生(只为方便理解,不是实际的原生)
function Promiesyd(callback){
var vmy = this;
vmy.flag = false;//标记是否进去resolve
vmy.flagerr = false;//标记是否进入reject
vmy.data;//存储成功时的数据
vmy.dataerr;//存储失败时的数据
var resolve = function(data2){ //5.执行成功函数,注入数据
vmy.flag = true;
vmy.data = data2;
}
var reject = function(data2){
vmy.flagerr = true;
vmy.dataerr = data2;
}
callback?callback(resolve,reject):''; //3.给匿名函数注入数据resolve,reject
this.then = function(success,err){ //7.监听异步是否执行完了,
var intervalx = setInterval(function(){
if(vmy.flag){
success(vmy.data);
clearInterval(intervalx);
}
if(vmy.flagerr){
err(vmy.dataerr);
clearInterval(intervalx);
}
},50);
}
}
var istrue = true;
function q1(){
return new Promiesyd(function(resolve,reject){ //1.new Promies 2.传递匿名函数,
$timeout(function() { //4.调用注入进来的resolve,reject
if(istrue){
resolve("异步执行成功1!!!");
}else{
reject("异步执行失败1!!");
}
}, 3000);
});
}
q1()
.then(function(data){ //6.调用then方法
console.log(data);
},function(data){
console.log(data);
})
2.7.3$q.all原生(只为方便理解,不是实际的原生。q1()、q2()的实现参考$q原生)
function allyd(promiesArr){
var flag = false;//判断数组是否为空 即:是否进for循环
var flagAll = false;//所有的promies是否执行完成
var dataArr = [];//存放执行后的promies数据
var intervalx1 = setInterval(function(){ //2.监听数组存在并执行完成
for(var i = 0;i < promiesArr.length;i++){
flag = true;
// console.log(promiesArr[i].flag);
if(promiesArr[i].flag){
dataArr.push(promiesArr[i].data);
promiesArr.splice(i,1);
i--;
}
}
if(flag&&promiesArr.length==0){ //数组存在并执行完成,清除定时器
flagAll = true;
clearInterval(intervalx1);
}
},50);
var obj = {};
obj.then=function(success){
var intervalx2 = setInterval(function(){ //4.监听是否可以执行.then()
// console.log("xx");
if(flagAll){
success?success(dataArr):'';
clearInterval(intervalx2);
}
},50);
};
return obj;
}
allyd([q1(),q2()]) //1.addyd()的调用
.then(function(data){ //3.执行.then()
console.log(data);
});
2.8 ui-router
$stateProvider
2.9 $log
// 使用日志服务
App.controller('DemoController', ['$log', function ($log) {
$log.info('普通信息');
$log.warn('警告信息');
$log.error('错误信息');
$log.log('打印信息');
$log.debug('调试信息');
}]);