Angular基础
Angular表达式:
{{}},如果要输出字符串{{“name”}}
数据双向绑定:改变了view的值,影响了model,model的改变又影响了view。
Ng-model=”name” value=””
<input type="text" ng-model="name"value="12">
{{name}}
<input type="text" ng-model="name"value="12">
<div ng-controller="first"></div> :first 是个表达式它会找一个first变量。
<divng-bind="age"></div>
<divng-bind="name"></div> 替换我们的{{}}的表达式。因为{{name}}会有延时。
控制器的控制器:
作用域链和Javascript连一样。向外找。本地没有,就向外找。如果有就不向找。外部元素不能向里找。
$scope是一个指向应用model的object,也是表达式的上下文
{{name}} 就是{{$scope.name}}
每个属性都写一个方法,
<div id="a">
obj.b
</div>
</div>
<script>
varobj={b:300,set:function(key,value){
obj[key]=value;
document.querySelector('a').innerHTML=value;
}}
obj.set('b',300);
脏检查:就是把我的变量在复制一份,每隔时间去检查一下,如果变了,就改变,you
性能问题。
Angular应用的是脏检查,不会检查所有的属性,列为html会自动检查。
Ng-controller初始化的时候就会脏检查。
$scope.$apply 触发脏检查。
setInterval(function(){
$scope.$apply(function(){
$scope.date=newDate();
});
},1000);
$appay 会检查$scope下所有变量。 方法会触发$digest()方法。不能直接用$digest() 方法。
中间有个$eval门卫。如果带的表达式不和法。$eval会把错误
交给$excepHandler。所以更安全。
$digest会触发$watch
$watch给我们手动监听对象。
//监听一个model,当一个model每次改变的时候。都会触发第二个函数。
$scope.$watch('name',function(newValue,oldValue){
++$scope.count;
if($scope.count>30)
{
$scope.name='da yu 30';
}
})
$wathch的第三个对象:
$scope.$watch('data',function(){
},true)
$scope.data={
name:'lisi',
count:20
}
会检查data中的每个对象。
什么是module
Angular没有main方法
Ng-bind ng-show ng-repeat 是指令;
模块定义:
Var myApp=angular.moudle(‘myApp’,[]);
myApp.controller('first',function($scope){
$scope.name="zhansan";
});
<div ng-app="myApp">
<div ng-controller="first">
{{name}}
</div>
First的控制器属于myApp模块的。如果ng-app=“”为
Angular全局模块
var myApp=angular.module('myApp',[],function($provide){
//自定义服务
$provide.provider('customservice',function(){
this.$get=function()
{
return{
message:'liyulong'
}
}
});
});
myApp.controller('first',function($scope,customservice){
$scope.name="zhansan";
console.log(customservice);
});
varmyApp=angular.module('myApp',[],function($provide){
//自定义服务
$provide.provider('customservice',function(){
this.$get=function()
{
return{
message:'liyulong'
}
}
});
//自定义工场
$provide.factory('service1',function(){
return[1,2,3,4];//可以任意类型。
});
//自定义服务
$provide.service('servece2',function(){
return ['shanghai'];//必须是对象
});
});
多个控制器,共享数据
var myApp=angular.module('myApp',[]);
myApp.factory('data',function(){
return {
message:'shard'
};
})
myApp.controller('first',function($scope,data){
//$scope.data={name:'zhangsan'};
$scope.data=data;
});
myApp.controller('second',function($scope,data){
//$scope.data=$scope.$$prevSibling.data;
$scope.data=data;
});
div ng-app="myApp">
<div ng-controller="first">
<input type="text" ng-model="data.message">
first:{{data.message}}
</div>
<div ng-controller="second">
<p>
second:{{data.message}}
</p>
</div>
</div>
Angular过滤器:
筛选的函数:
种类:
{{12345| number}}
{{12345| number:3}}
货币
{{120|currency}}
{{120|currency:'#'}}
日期
{{date|date:'medium'}}
{{date|date:'y'}}
{{[1,2,3,4,5]|limitTo:-4}}
{{money|uppercase}}
{{data.city|filter:'shanghai'}}
{{data.city| filter:{py:'bj'} }} 注意最里层的一个括号,和两个括号有空格
orderBy排序:
{{data.city| orderBy:'py'}}
反序
{{data.city| orderBy:'-py'}}
Json:
myApp.controller('product',function($scope,data,$filter){
var str=$filter('json')($scope.data);
自定义过滤器:
{{data.city|filter:checkName}}
$scope.checkName=function(obj){
console.log(obj);
if(obj.py.indexOf('h')===-1)
{
return false;
}
else
{
return true;
}
}
搜索功能:
<tr ng-repeat="item in productData|filter:'33'" >
<tr ng-repeat="item in productData|filter:search" >
排序:
<tr ng-repeat="item in productData|filter:search|orderBy:'-id">
<tr ng-repeat="item inproductData|filter:search|orderBy:'order+orderType'" >
tr>
<thng-click="changOrder('id')" ng-class="{dropup:order==''}">
产品编号<spanng-class="{orderColor:orderType==='id'}" class="caret"></span>
</th>
<thng-click="changOrder('name')" ng-class="{dropup:order==''}">
产品名称 产品编号<span ng-class="{orderColor:orderType=='name'}"class="caret"></span>
</th>
<thng-click="changOrder('price')"ng-class="{dropup:order==''}">
产品价格 产品编号<span ng-class="{orderColor:tt=='nu'}"class="caret"></span>
</th>
</tr>
myApp.controller('product',function($scope,data){
$scope.productData=data;
$scope.orderType='id';
$scope.order='-';
$scope.changOrder=function(type)
{
$scope.orderType=type;
if($scope.order==='')
{
$scope.order='-'
}
else
{
$scope.order='';
}
}
});
自定义过滤器:
myApp.service('data',function($filterProvider){
$filterProvider.register('filterAge',function(){
});
armyApp=angular.module('myApp',[],function($provide){
//自定义服务
$provide.provider('customservice',function(){
this.$get=function()
{
return{
message:'liyulong'
}
}
});
//自定义过滤器
Var myapp=angular.module(‘myapp’,[],function($filterProvider,$provide,$controllerProvider){
$provide.service(‘data’,function(){
});
$filterProvider.register(‘filterAge’,function(){
Return function(obj)
{
Return obj;
}
});
$controllerProvider.register(‘first’,function($scope,data){
})
});
Myapp.service(‘data’,function(){
})
Myapp.controller(‘first’,function($scope,data,$filter){
})
完整的demo
<div ng-app="myApp">
<div ng-controller="first"class="container">
<ul>
<ling-repeat="user in data|filterAge">
{{user.age}}
{{user.name}}
{{user.city}}
</li>
</ul>
</div>
var myApp=angular.module('myApp',[],
function($filterProvider,$provide,$controllerProvider){
$provide.service('data',function(){
return [
{
name:'zhansan',
age:20,
city:'shanghai'
},
{
name:'lisi',
age:30,
city:'beiji'
},
{
name:'wangwu',
age:90,
city:'nanjing'
}
]
});
$filterProvider.register('filterAge',function(){
return function(obj)
{
var newobj=[];
angular.forEach(obj,function(o){
if(o.age>20)
{
newobj.push(o);
}
});
return newobj;
}
});
$controllerProvider.register('first',function($scope,data){
$scope.data=data;
});
})
自定义过滤器另一种写法:
//module.filter
myApp.filter('filterCity',function(){
return function(obj)
{
var newobj=[];
angular.forEach(obj,function(ob){
if(ob.city=='shanghai')
{
newobj.push(ob);
}
});
return newobj;
}
});
正确的使用controller,
不要在controller做以下事情:
1.任何类型的dom操作。
2.不要做输入格式
3.输出格式化过滤
4.执行无状态的,
5.实例化,或者管理其他的生命周期。
//controller 常用的方法,压缩的时候,$scope 会被替换。
myapp.controller('second',['$scope',function(a){
console.log(a);
}]);
//显示的依赖注入
myapp.controller('second',['$scope','$filter',function(a,b){
console.log(a);
}]);
依赖注入service
注入window,只有controller中加入data,才能调service注入。
myapp.factory('data',['$window',function(a){
console.log(a);
}]);
myapp.controller('second',['$scope','$filter','data',function(a,b,c){
//console.log(a);
}]);
//隐士的依赖注入
myapp.controller('second',function($scope,$filter,data){
});
//全局的注入
function otherController(a)
{
console.log(a);
}
otherController.$inject=['$scope'];
什么是指令:ng-appng-class
渲染指令:
<p ng-bind="1+2"></p>
//可以顺利通过校验
<pdata-ng-bind="1+2"></p>
<div ng-include=”’other.html’”></div>//里面必须是单引号
<ul ng-init="city=['shanghai','bj']">
<li ng-repeat="item in city">
<span>{{$index}}</span>
<span>{{$first}}</span>
<span>{{$middle}}</span>
<span>{{item}}</span>
</li>
</ul>
//节点指令:ng-style,注意margin-top等必须是单引号,如'margin-top':'50px','font-size':'10px'
<divng-style="{color:'red','margin-top':'50px','font-size':'10px'}">
ng-style
</div>
也可以写在控制器中:
$scope.defaultStyle={
'color':'red',
'font-size':'10px'
};
<divng-style=defaultStyle>
Ng-class节点
<div ng-style=defaultStyle ng-class="{red:true}">
<li ng-class-even=” ‘偶数’”>
Ng-show
<div ng-style=defaultStyle ng-class="{red:true}"ng-show="false">
Ng-switch:
<ul ng-switch on=”status”>
<li ng-switch-when=”1”>1</li>
<li ng-switch-when=”2”>2</li>
<div>
<ul ng-switch on="status">
<ling-switch-when="1">true</li>
<li ng-switch-when="2">false</li>
</ul>
</div>
<div ng-src={{}}>
<div ng-if=”status”>
Status show
</div>
自定义指令:
如果名字为XXX-yyy 那么在定义指令时应该是xxxYyy
Restrict:属性的风格。
a.directive('customTags',function(){
return{
restrict:'E',
template:'<div>custom-Tags-html</div>'
}
});
<custom-Tags>111</custom-Tags> //注意<custom-Tags>要-分开。
E: <custom-tags></custom-tags>//元素标签
C <div class=’custom-tags’></div>//类别标签
A <divcustom-tags></div>//属性标签
<div ng-app="myApp">
<custom-Tags>111</custom-Tags>
<divclass="custom-tags"></div>
<div custom-tags >
</div>
var myapp=angular.module('myApp',[],['$compileProvider',function(a){
a.directive('customTags',function(){
return{
restrict:'ECA',
template:'<div>custom-Tags-html</div>',
replace:true
}
});
}]);
Replace:false 的情况下:
Replace:true
templateUrl
var myapp=angular.module('myApp',[]);
myapp.directive('customTags',function(){
return{
restrict:'ECM',
templateUrl:'tmp/other.html',
replace:true
}
});
myapp.controller('first',['$scope',function($scope){
$scope.name="zhansan";
}]);
Other.html:
<div>
{{name}}
</div>
//替换javascript模板;
1.
<javascript type=”text/ng-template” id=”cus”>
<div>name</div>
</javascript>
2.
myapp.directive('customTag2',function(){
return{
restrict:'ECM',
templateUrl:'cus2',
replace:true
}
});
3.<custom-tom2><custom-tom2>
保留旧数据:
myapp.directive('customTag3',function(){
return{
restrict:'ECM',
template:'<div>liyulong<spanng-transclude></span></div>',
replace:true,
transclude:true
}
});
myapp.directive('customTag3',function(){
return{
restrict:'ECM',
template:'<div>liyulong<span ng-transclude></span></div>',
replace:true,
transclude:true,
priority:0,
//小于0的directive 都不会执行
terminal:true
}
});
Angularjs 编译的三个阶段
将html转换为dom
搜索匹配directive,按照priority排序。并执行directive上的compile方法
有两个指令的话,只能有一个template。
//1.将div转换为dom
2.搜索匹配的directive 默认的优先级为0,那个先定义那个先使用。
<div my-tag you-tag></div>
Compile方法必须有个返回值,就是link函数,所以定义compile,就不要定义link了
<div ng-repeat="user in users"my-tag you-tag></div>
Ng-repeat 会产生两个my-tag, 作用域scope有两个。
Compile函数的参数:
compile:function(tElement,tAttrs,transclude)
注意:template:'<div><divng-repeat="item in books">{{item.name}}</div></div>',是对的
template:'<div ng-repeat="item inbooks">{{item.name}}</div>'
是错的,div必须有一个容器。
Link:
var app=angular.module('myApp',[]);
app.directive('helloworld',function(){
return{
restrict:'AE',
template:'<h3 style="color: {{color}}">helloworld</h3>',
replace:true,
link:function(scope,elem,attrs){
elem.bind('click',function(){
elem.css('color','red');
});
}
// link:function(scope,elem,attrs){
// console.log(elem);
//
// console.log(scope);
// elem.bind('click',function(){
// elem.css('background-color','red');
// scope.$apply(function(){
// scope.color='blue';
// });
//
// });
// }
}
})
app.controller('first',function($scope){
$scope.name="zhangsan";
});
Compile: pre, post
var app=angular.module('myApp',[]);
app.directive('helloworld',function(){
return{
restrict:'AE',
template:'<h3 style="color: {{color}}">helloworld</h3>',
replace:true,
compile:function(tElement,tAttrs,transclude)
{
return{
pre:function prelink()
{
console.log('custom prelink');
},
post:function postLink(scope,iElement,iAttrs,controller)
{
iElement.bind('click',function(){
scope.$apply(function(){
scope.color='red';
});
});
console.log('custom postlink');
}
}
},
link:function(scope,elem,attrs){
elem.bind('click',function(){
elem.css('color','red');
});
}
// link:function(scope,elem,attrs){
// console.log(elem);
//
// console.log(scope);
// elem.bind('click',function(){
// elem.css('background-color','red');
// scope.$apply(function(){
// scope.color='blue';
// });
//
// });
// }
}
})
app.controller('first',function($scope){
$scope.name="zhangsan";
});
Controller:
//varmyapp=angular.module('myApp',[],['$compileProvider',function(a){
//
// a.directive('customTags',function(){
//
// return{
//
// restrict:'ECA',
// template:'<div>custom-Tags-html</div>',
// replace:true
//
//
// }
// });
//
//}]);
var myapp=angular.module('myApp',[]);
myapp.directive('bookList',function(){
return{
restrict:'ECAE',
template:'<ul><ling-repeat="book in books">{{book.name}}</li></ul>',
replace:true,
controller:function($scope)
{
console.log($scope);
$scope.books=[
{
name:'php'
},
{
name:'javascript'
},
{
name:'java'
}
];
this.addbook=function()
{
alert('s');
}
},
controllerAs:'bookListController',
link:function(scope,iEelement,iAttrs,bookListController)
{
// iEelement.bind('click',function(){
//
// alert('a');
//
// });
iEelement.bind('click',bookListController.addbook);
}
}
});
myapp.controller('first',['$scope',function(scope){
// scope.books=[
//
// {
// name:'php'
// },
// {
// name:'javascript'
// },
// {
// name:'java'
// }
//
// ];
}]);
Require属性,可以将其他指令传递给自己。
template:'<ul><ling-repeat="book inbooks">{{book.name}}</li></ul><book-add></book-add>',是错误的应该放在div中:
如下:
<div><ul><ling-repeat="book inbooks">{{book.name}}</li></ul><book-add></book-add></div>
Require属性
require:'^bookList',,就可以共享bookList的controller
controllerAs:'bookListController'了,
共享之后,在link中就可以自动注入
link:function(scope,iElement,iAttrs,bookListController)
{
iElement.bind('click',bookListController.addbook);
}
这样就可以调用上一个命令的function,
require:'^bookList'。向上找。
Demo:
//varmyapp=angular.module('myApp',[],['$compileProvider',function(a){
//
// a.directive('customTags',function(){
//
// return{
//
// restrict:'ECA',
// template:'<div>custom-Tags-html</div>',
// replace:true
//
//
// }
// });
//
//}]);
var myapp=angular.module('myApp',[]);
myapp.directive('bookList',function(){
return{
restrict:'ECAE',
template:'<div><ul><li ng-repeat="book inbooks">{{book.name}}</li></ul><book-add></book-add></div>',
replace:true,
controller:function($scope)
{
$scope.books=[
{
name:'php'
},
{
name:'javascript'
},
{
name:'java'
}
];
this.addbook=function()
{
$scope.$apply(function(){
$scope.books.push(
{
name:'angular'
}
)
});
}
},
controllerAs:'bookListController',
link:function(scope,iEelement,iAttrs,bookListController)
{
// iEelement.bind('click',function(){
//
// alert('a');
//
// });
iEelement.bind('click',bookListController.addbook);
}
}
});
myapp.directive('bookAdd',function(){
return{
restrict:'ACE',
require:'^bookList',
template:'<button type="button">add</button>',
replace:true,
link:function(scope,iElement,iAttrs,bookListController)
{
iElement.bind('click',bookListController.addbook);
}
}
});
myapp.controller('first',['$scope',function(scope){
// scope.books=[
//
// {
// name:'php'
// },
// {
// name:'javascript'
// },
// {
// name:'java'
// }
//
// ];
}]);
Scope:false 是和controller里共享的一个scope。
Scope:true,创建一个独立有继承链的scope
scope:{
a:'&mks'
}
//将父元素books封装成一个a函数
会会将mks封装成一个函数,找到属性mks ,<book-listmks="books"></book-list>
找到父元素的books,
//varmyapp=angular.module('myApp',[],['$compileProvider',function(a){
//
// a.directive('customTags',function(){
//
// return{
//
// restrict:'ECA',
// template:'<div>custom-Tags-html</div>',
// replace:true
//
//
// }
// });
//
//}]);
var myapp=angular.module('myApp',[]);
myapp.directive('bookList',function(){
return {
restrict:'ECAE',
template:'<div><ul><li ng-repeat="book inbooks">{{book.name}}</li></ul><book-add></book-add></div>',
replace:true,
link:function(scope,iEelement,iAttrs)
{
iEelement.bind('click',scope.addname);
},
controller:function($scope)
{
console.log($scope.a());
$scope.books=$scope.a();
// $scope.books=[
//
// {name:'zhansan'},
// {name:'lisi'}
// ]
$scope.addname=function()
{
$scope.$apply(function(){
$scope.books.push({name:'zhangsan'});
});
}
},
scope:{
//将父元素books封装成一个a函数
a:'&mks'
}
}
})
myapp.controller('first',['$scope',function(scope){
console.log(scope);
scope.books=[
{
name:'php'
},
{
name:'javascript'
},
{
name:'java'
}
];
}]);
b:'=parentBk'
找到属性为parentBk对应的books,就会将生成一个b函数,封装books。=是双向绑定的。
不能应用对象,只能引用字符串。
<div ng-app="myApp">
<div ng-controller="first">
<book-listmks="books" parent-bk="books"parent-title="title"></book-list>
</div>
</div>
var myapp=angular.module('myApp',[]);
myapp.directive('bookList',function(){
return {
restrict:'ECAE',
template:'<div><ul><li ng-repeat="book inbooks">{{book.name}}</li></ul><book-add></book-add></div>',
replace:true,
link:function(scope,iEelement,iAttrs)
{
iEelement.bind('click',scope.addname);
},
controller:function($scope)
{
// console.log($scope.a());
// $scope.books=$scope.a();
// $scope.books=$scope.b;
// $scope.books.push({name:'gougou'});
console.log($scope.c);
console.log($scope.b);
// $scope.books=[
//
// {name:'zhansan'},
// {name:'lisi'}
// ]
$scope.addname=function()
{
$scope.$apply(function(){
$scope.books.push({name:'zhangsan'});
});
}
},
scope:{
//将父元素books封装成一个a函数
a:'&mks',
b:'=parentBk',
//使用简单的数据类型
c:'@parentTitle'
}
}
})
myapp.controller('first',['$scope',function(scope){
console.log(scope);
scope.books=[
{
name:'php'
},
{
name:'javascript'
},
{
name:'java'
}
];
scope.title='zhansan';
}]);
Scope属性:
<item ng-repeat="item in data"heading={{item.title}}></item>
scope:{
heading:'@heading'
}
Heading 就指向了item.title
在html中{{heading}}可以直接访问
template:'<div>{{heading}}</div>',
angular.module('myApp',[],['$provide',function($provide){
//$provide.value
}])
.value('venson','1.0.0')
.constant('APIKEY','xxx')
//value ,constant都可以注入controller
.controller('first',['APIKEY','venson',function(APIKEY,venson){
console.log(APIKEY);
console.log(venson);
console.log('controller');
}])
//只有constant可以注入config
.config(function(APIKEY){
console.log(APIKEY);
console.log('config');
})
//在config之后,在controller之前
.run(function(){
console.log('run');
});
Form 验证:
<div ng-app="myApp"style="margin-top: 100px">
<form name="myform" ng-controller="first"class="container" >
<div class="form-group">
<label class="col-sm-2 control-label">usser</label>
<div class="col-sm-10">
<input type="text"name="username" ng-required="true"ng-minlength="5" ng-maxlength="10"ng-model="data.username" class="form-control"id="exampleInputEmail1" placeholder="username">
{{myform.username.$error}}
</div>
</div>
</form>
</div>
{{myform.username.$error}}
Demo:
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet"href="../../vender/bootstrap3/css/bootstrap.min.css">
<meta charset="utf-8">
</head>
<body>
<div ng-app="myApp"style="margin-top: 100px">
<form name="myform" ng-controller="first"class="container" >
<div class="form-group"ng-class="{has-error:'myform.username.$dirty&&myform.username.$invalid'}">
<label class="col-sm-2control-label">usser</label>
<div class="col-sm-10">
<input type="text"name="username" ng-required="true"ng-pattern="/^[a-zA-Z]{1}/" ng-minlength="5"ng-maxlength="10" ng-model="data.username"class="form-control" id="exampleInputEmail1"placeholder="username">
{{myform.username.$error}}
<div class="alertalert-danger help-block"ng-show="myform.username.$error.maxlength" >
username max length is too long
</div>
<divng-show="myform.username.$error.minlength" class="alertalert-danger help-block" >
username max length is low
</div>
<div ng-show="myform.username.$error.pattern"class="alert alert-danger help-block" >
username max length ispattern
</div>
</div>
</div>
</form>
</div>
<script type="text/javascript"src="../../vender/angular/angular.js"></script>
<script type="text/javascript"src="app/index.js" charset="UTF-8"></script>
</body>
</html>
<divng-show="myform.email.$error.email" class="alert alert-dangerhelp-block" >
<divng-show="myform.email.$error.url" class="alert alert-dangerhelp-block" >