AngularJS 有哪些特性?
- MVC模式
- 模块系统
- 指令系统
- 依赖注入
- List item
- 双向数据绑定
1、指令
- ng-app
- ng-view —— 配合ngRouter插件使用
- ng-controller
- ng-model ——
<input type="text" ng-model="text" ng-model-options="{updateOn : 'blue'}" >
失去光标时候触发改变text值 - ng-repeat ——
$index、$first、$last、$even、$odd
- ng-click
- ng-mousedown/up
- ng-mouseenter/leave
- ng-mousemove/over/out
- ng-keydown/up/press
- ng-fouse/blur
- ng-submit
- ng-selected —— 改变下拉框当前选中值
- ng-change —— 输入框值改变的时候
- ng-copy
- ng-cut
- ng-paste —— 粘贴
- ng-disabled
- ng-readonly
- ng-checked —— 单选框或复选框选中状态
- ng-value —— 这样表达式就不会展示給客户端了
- ng-minlength
- ng-maxlength
- ng-pattern —— 正则验证表单
- ng-bind —— 效果跟 ng-value 类似
- ng-bind-template ——
<div ng-bind-template="{{text}},{{text}}"></div>
可以写多个表达式 - ng-bind-html —— 解析标签,需要用插件。
- ng-cloak ——
<div ng-cloak>{{text}}</div>
没有解析完前 元素是display:none;也实现了表达式不会出现在客户端中 - ng-class
- ng-style
- ng-href
- ng-src
- ng-attr-(suffix) —— 自定义写法如angular里面没有的
ng-attr-title、ng-attr-src(等于:ng-src)
- ng-show
- ng-if
- ng-hide
- ng-switch
- ng-open —— 給 details 标签用的 h5的薪标签,对火狐不兼容
- ng-init —— 在html里定义变量,在循环的时候定义indx时候用到
- ng-include ——
<div ng-include="'aaa.html'"></div>
通过模板方式引入文件,类似 iframe
// controller as , 解决了父子$scope带来的混乱
// angularJS中面向对象的写法
var m1 = angular.module('myApp',[]);
m1.controller('Aaa,['$scope',fnAaa]');
function fnAaa($scope){
fnAaa.prototype.num = '123';
fnAaa.prototype.show = function(){
return 'hello';
};
}
// html
<div ng-controller="fnAaa as a1"> // a1 是任意命名
<div>{{a1.num}} {{a1.show}}</div>
</div>
//ng-bind-html
// 第一步:引入插件
<script src="https://cdn.bootcss.com/angular.js/1.3.2/angular-sanitize.js"></script>
// 第二步:模块化导入插件
var m1 = angular.module('myApp',['ngSanitize']);
m1.controller('Aaa,['$scope',function($scope){
$scope.text = '<h1>hello</h1>';
}]');
// 第三步:html里面使用
<div ng-bind-html="text"></div>
2、依赖注入(服务)
- $scope
- $ scope.$watch —— 有三个参数:1、监听地对象 2、监听回调 3、是否进行深度地监听:true 或 false
- $ scope.$apply —— 结合js原生方法改变数据值。
- $rootScope
- $timeout
- $interval
- $filter
- $http ——
method、url、success、error
- $location ——
'absUrl()、 path()、 replace()、hash()、search()、 url()、 host()、port()、 portocol()'
可以拿到浏览器地址 - $anchorScroll —— 锚点跳转
- $cacheFactory ——
info()、put()、get()、remove()
设置缓存 - $log —— 跟console.log() 类似
- $interpolate —— 插值,如在表单中输入{{name}} 可以正确的在div中展示出name的数据
- $q ——
defer()、resolve、reject()、notify()、then()
跟promise类似 - provider —— 供应商(m1.config()) , 改变表达式 {{name}} 、可以改成@@name@@
// $q
var m1 = angular.module('myApp',[]);
m1.controller('Aaa',['$scope','$q',function($scope,$q){
var dfd = $q.defer(); // 创建延迟对象
function show(){
setTimeout(function(){
// dfd.resolve(); // 成功
dfd.reject(); // 失败
})
return dfd.promise
}
show().then(function(){
// console.log('成功')
},function(){
// console.log('失败')
})
}])
// $cacheFactory
var m1 = angular.module('myApp',[]);
m1.controller('Aaa',['$scope','$location',function($scope,$cacheFactory){
var cache = $cacheFactory('myCache');
cache.put('name','suzy'); // 设置
// console.log(cache.get('name')); // 获取
// cache.remove(); 清楚
}])
// $location
var m1 = angular.module('myApp',[]);
m1.controller('Aaa',['$scope','$location',function($scope,$location){
$location.path('aaa/bbb'); // 路由后面会加上 '#/aaa' (www.baidu.com/#/aaa) 有历史记录可以返回上一页
// $location.path('aaa/bbb').replace(); // 没有历史记录不可返回上一页
$location.search({'age':'20'}) // 路由后面会加上 ——'?age=20'
// port 获取端口、 portocol 获取协议方式 http\https
}])
// $http
var m1 = angular.module('myApp',[]);
m1.controller('Aaa',function($scope){
$http({
method : 'GET',
url : 'data.php',
}).success(function(data,state,headers,config){
// console.log(data)
}).error(function(data){
// console.log(data)
})
// 下面是简写方式
$http.get(data.php).success(function(data,state,headers,config){
// console.log(data)
}
})
// $scope.$watch
$scope.phone = {
money:5,
num:1
}
$scope.$watch('phone',function(newVal,oldVal){
console.log(newVal)
},true)
// $interval
var iNow = 5;
var timer = $interval(function(){
iNow--;
$scope.text = iNow + '秒';
if(iNow == 0){
$interval.cancel(timer) // 清除定时器
$scope.text = '可点击';
}
},1000)
// $scope.$apply
setTimeout(function(){
$scope.$apply(function(){ // 此时,如果不用 $scope.$apply 是改变不了name的
$scope.name = 'xiaoming';
})
},1000)
// $filter - js 中使用过滤器
$scope.name = $filter('uppercase')('hello');
console.log($scope.name); // HELLO
3、过滤器
- currency ——
{{ money | currency:'¥'}}
- number ——
{{ money | number:4}}
,将数字加上分隔符,默认保留三位小数点 - lowercase/uppercase —— 转大小写
- json ——
<pre id="custom-spacing">{{ {'name':'value'} | json:4 }}</pre> ,在<pre> 标签里面显示json的格式
- limitTo ——
{{name | limitTo:2}}
截取字符串或数组 - date ——
{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
时间戳转日期格式 - orderBy —— 排序,默认从小到大,加上 :true 则 从大到小
- filter —— 过滤器,默认模糊匹配,加上:true 则严格匹配
// orderBy
$scope.arr1 = [
{color:'red',age:'20'},
{color:'pink',age:'22'},
{color:'blue',age:'55'},
]
<div> {{arr1 | orderBy: 'age': true}}</div>
// filter
$scope.arr1 = [
{color:'red',age:'20'},
{color:'pink',age:'22'},
{color:'blue',age:'55'},
]
<div> {{arr1 | filter : 'red' : true}}</div>
4、模块化
angular.module 模块下面的方法:controller、run 、filter、 directive、 factory、 provider、 service、 constant、 value
— controller
// controller
var m1 = angular.module('myApp',[]);
m1.controller('Aaa',function($scope){
// 这样写 代码压缩有会出现问题
})
m1.controller('Aaa',['$scope',function($scope){
// 这样写 解决了代码压缩的问题
}])
— run
// run 全局作用域
m1.run(['$rootScope'],function($rootScope){
$rootScope.name = 'suzy';
})
— 自定义过滤器 (filter)
// filter
$scope.name = 'suzy';
m1.filter('filterName',function(){
return function(str){
// console.log(str); // suzy
return str.charAt(0).toUpperCase() + str.substring(1); // 首字母大写
}
});
<div>{{name | filterName }}</div>
— 自定义指令 (directive)
// (restrict、replace、template、templateUrl)
var m1 = angular.module('myApp',[]);
m1.directive('directiveName',function(){
return {
restrict: 'E' // 指令类型: E:标签 ,A:属性,C:类名,M:注释,可以组合使用。
template: '<div>hello</div>',
// templateUrl:'aaa.html', 可以引入外部文件
replace: true, // 替换模板
transclude: true, // 可以指令嵌套指令
scope: {}, // 隔离作用域
// scope: true, // 独立作用域
scope: { // 绑定策略 @、=、&
myId:'@', // 原样解析
myName:'=' // 解析数据
myFn:'&' // 函数传递
},
controller:['$scope',function($scope){ // 常用于指定间有共同的属性或者方法的时候
$scope.name = 'aaa';
$scope.show = function(num){
console.log(num)
}
}],
link:function(scope,element,attr,reController){ // 常用于dom处理和指令间的数据交互
// console.log(scope.name) // scope:拿到数据
// console.log(element) // attr: 拿到指令里最外层的dom
// console.log(attr.myId) // attr: 拿到指令上面的属性值
}
}
})
<div>
<directive-name my-id='div1' my-name='name' my-fn='show(num)' ></directive-name>
<directive-name my-id='div2' my-name='name' my-fn='show(num)' ></directive-name>
</div>
// aaa.html
<div id='{{myId}}'>
<input type='button' value='按钮' ng-click='myFn(333)' >
<div>{{name}}</div>
</div>
— 指令间的交互
// (restrict、replace、template、templateUrl)
var m1 = angular.module('myApp',[]);
m1.directive('hello',function(){
return {
restrict: 'E'
replace: true,
transclude: true, // 可以指令嵌套指令
template: '<div>hello <h1 ng-transclude></h1> </div>', // hi 指令内容都放在了 h1中。
controller:['$scope',function($scope){
this.name = 'aaa'; // 不能用scope, 要用this 这样数据才能传递給子指令
}],
}
})
m1.directive('hi',function(){
return {
restrict: 'E'
replace: true,
require:'^hello', // hello 是指令名字, ^ 是要去父级拿数据不写是在自身,除非子指令是以属性的方式在父指令上就不用写^。
template: '<div>hi</div>',,
link:function(reController){
// console.log(reController) // scope:拿到数据
}
}
})
<div>
<hello>
<hi></hi>
</hello>
</div>
// aaa.html
<div id='{{myId}}'>
<input type='button' value='按钮' ng-click='myFn(333)' >
<div>{{name}}</div>
</div>
— 自定义服务 (factory)
// factory 自定义服务 (不可进行供应商操作)
var m1 = angular.module('myApp',[]);
m1.factory('serviceName',['$scope',function($scope){
return {
name:'hello',
show:function(){
return this.name + 'angular';
}
}
}])
m1.controller('Aaa',['$scope','serviceName',function($scope,serviceName){
// console.log(serviceName.show());
}])
— 自定义服务 (provider)
// provider 自定义服务 (可进行供应商操作)
var m1 = angular.module('myApp',[]);
m1.provider('serviceName',['$scope',function($scope){
return {
$get:function(){
return {
name:'hello',
show:function(){
return this.name + 'angular';
}
}
}
}
}])
m1.controller('Aaa',['$scope','serviceName',function($scope,serviceName){
// console.log(serviceName.show());
}])
— 自定义服务 (service)
// service 自定义服务
var m1 = angular.module('myApp',[]);
m1.service('serviceName',['$scope',FnService);
function FnService(){
this.name = 'suzy';
}
FnService.prototype.age = 22;
m1.controller('Aaa',['$scope','serviceName',function($scope,serviceName){
// console.log(serviceName.name);
// console.log(serviceName.age);
}])
// constant value 是设置常量的 用的不多
5、angularJs 工具方法
- angular.bind —— 改变this指向
- angular.copy —— 对象复制
- angular.extend —— 对象继承
- angular.isArray ——
console.log(angular.isArray([1,2,3])) // true
- angular.isDate
- angular.isDefined
- angular.isUndefined
- angular.isFunction
- angular.isNumber
- angular.isObject
- angular.isString
- angular.isElement
- angular.version —— 查看angular版本
- angular.equals ——
angular.equals(123,'123'))
判断2个元素是否相等- angular.forEach
- angular.fromJson/toJson —— 字符串转json / json转字符串, 跟 原生
JSON.stringify
不同的是.toJson({},true)
可以将字符串打印成json的格式方便阅读- angular.identity/noop
- angular.lowercase/uppercase —— 大小写转换
- angular.element —— 获取元素:
angular.element(document.getElementById('div1')).css('color','red');
- angular.bootstrap —— 动态初始化,
angular.bootstrap(document, ['myApp']);
(就不需要写 ng-app=“mgApp” 了)- angular.injector —— 注册器
// angular.bind // 改变this指向
function(n1,n2){
console.log(n1)
}
angular.bind(document,show,2,3)();
// angular.copy // 对象复制
var a = {
name : 'suzy';
}
var b = {
age : '20';
}
var c = angular.copy(a);
console.log(c); // {name : 'suzy';}
var c = angular.copy(a,b); // a 把所有值覆盖给了 b
// console.log(c); // {name : 'suzy';}
// console.log(b); // {name : 'suzy';}
// console.log(a); // {name : 'suzy';}
// angular.extend // 对象继承
var a = {
name : 'suzy';
}
var b = {
age : '20';
}
var c = angular.extend(b,a);
console.log(b); // {name : 'suzy',age : '20';}
// angular.forEach
var arr = [1,2,3,4];
angualr.forEach(arr,function(value,index){
console.log(value)
})
// 如 对数组里面的值做处理 forEach 还有第三个参数
var result = [];
angualr.forEach(arr,function(value,index){
this.push(value + 2);
},result)
console.log(result); // [2,4,6,8]
6、angularJS 表单验证
- $valid —— 有效值
- $invalid —— 无效值
- $pristine —— 初始值
- $dirty —— 脏值
- $error
// form 有个 novalidate 属性阻止默认行为。
<form novalidate name="myForm">
<input type="text" name="myText" ng-model="text" ng-min-length="5" ng-pattern="/^[a-zA-Z]+$/" >
<div>{{myForm.myText.$valid}}</div>
<div>{{myForm.myText.$dirty}}</div>
</form>
— 表单验证实例
// ng-repeat 里面也可以用过滤器
$scope.regText = {
regVal : 'default',
regList : [
{name : 'default' , tips : '请输入用户名'},
{name : 'required' , tips : '用户名不能为空'},
{name : 'pattern' , tips : '用户名必须是字母'},
{name : 'pass' , tips : '验证成功'},
],
change : function(error){
// console.log(error)
for(var attr in err){
if(err[attr] == true){
this.regVal = attr;
return;
}
this.regVal = 'pass';
}
}
}
<form novalidate name="nForm">
<div>
<label>用户名:</label>
<input type='text' name='nText' ng-model='regText.name' required ng-patten="/^[a-zA-Z]+$/" ng-blur='regText.change(nForm.nText.$error)' >
<span ng-repeat='re in regText.regList | filter : regText.regVal' >{{re.tips}}</span>
</div>
</form>
7、AngularJs 插件
- ngSanitize —— 解析标签
- ngAnimate
- ngResource ——
支持REDTful架构模式、 get()、query()、save、delete
- ngRouter ——
ng-view、$routeProvider(when -> template,templateUrl)、otherwise、$routeParams
单页面路由操作 - 路由事件 ——
$on、$routeChangeStart、$routeChangeSuccess/Error
— ngSanitize
// 第一步:引入插件
<script src="https://cdn.bootcss.com/angular.js/1.3.2/angular-sanitize.js"></script>
// 第二步:模块化导入插件
var m1 = angular.module('myApp',['ngSanitize']);
m1.controller('Aaa,['$scope',function($scope){
$scope.text = '<h1>hello</h1>';
}]');
// 第三步:html里面使用
<div ng-bind-html="text"></div>
— ngResource
var m1 = angular.module('myApp',['ngSanitize']);
m1.controller('Aaa,['$scope','$resource',function($scope,$resource){
var objRe = $resource('aaa.json');
// console.log(objRe.get()); // 拿到 aaa.json 里面的数据
}]');
— ngRouter
// 第一步:引入插件
<script src="https://cdn.bootcss.com/angular.js/1.6.10/angular-route.min.js"></script>
// 第二步:模块化导入插件
var m1 = angular.module('myApp',['ngRouter']);
m1.config(['$routeProvider'],function($routeProvider){
$routeProvider.when('/aaa/:num',{
template : '<p>111111</p> {{name}}', // 111111 hello
controller:'Aaa'
}).when('/bbb',{
template : '<p>22222</p> {{name}}', // 22222 hi
controller:'Bbb'
});
// 如果想默认显示 '/bbb'
.otherwise({
redirecTo:'/bbb',
})
})
m1.controller('Aaa,['$scope','$location','$routeParams',function($scope,$location,$routeParams){
// console.log($routeParams); // 可以拿到路由传的参数
$scope.name = 'hello';
$scope.$location = $location;
}]');
m1.controller('Bbb,['$scope',function($scope){
$scope.name = 'hi';
}]');
<div ng-controller="Aaa">
// <a href='#aaa' >首页</a>
// <a href='#bbb' >列表</a>
// 或者
<a ng-click='$location.path('aaa/111')'>首页</a>
<a ng-click='$location.path('bbb/222')'>列表</a>
<div ng-view></div>
</div>
— 路由切换事件
var m1 = angular.module('myApp',['ngSanitize']);
m1.run(['$rootScope'],function($rootScope){
$rootScope.$on('$routeChangeStart',function(event,current,pre){
// console.log('route Change star')
})
})
m1.controller('Aaa,['$scope',function($scope){
}]');
8、 AngularJs 事件
- $emit —— 事件向上传播
- $broadcast —— 事件向下传播
- event ——
targetScope、currentScope、name、stopPropagation()
- 内部传播方式 ——
$routeChangeStart 、 $viewContentLoaded