AngularJS--双向数据绑定
Google AngularJS是一个JS框架,适用于以数据操作为主的SPA应用。所有的操作都是以数据为出发点。四大特性:
(1)MVC模型
Model:即业务数据 $scope.xx $rootScope.xx
View:即业务数据的呈现 HTML + ngXxx
Controller:负责操作业务数据 .controller('', function(){})
(2)双向数据绑定
方向1:Model绑定到View,只要Model变View随着变
方向2:View(表单控件)绑定到Model,只要View变Model随着变
(3)依赖注入
(4)模块化设计
面试题:AngularJS的最大的不足/应用时需要特别关注的地方? 原生ES/JS/DOM只有特定HTML元素的特定事件的监听机制,没有监听数据/对象/值改变的机制。
|
$interval和window.setInterval()的区别? $interval修改的任何Model数据,底层会立即遍历一遍$digest队列; setInterval()即使修改了Model数据,也不会遍历$digest队列; |
$interval(function(){ $scope.count++; }, 1000) 等价于 setInterval(function(){ $scope.count++; $digetst()/$apply(); }, 1000) |
2.依赖注入
Dependency:若某个函数调用时需要其它的对象作为形参,就此函数依赖于形参对象。
function Driver( car ){ //司机依赖于一个car对象
car.start();
car.run();
car.stop();
}
如何解决依赖关系:
(1)主动创建方式
var c1 = new Car(); //主动创建依赖对象
var d1 = new Driver( c1 ); //传递依赖对象
(2)被动注入(Injection)方式
module.controller('控制器', function($scope, $interval){})
Angular中的ngController指令在实例化控制器对象时,会根据指定的形参名,创建出控制器所依赖的对象,并注入给控制器对象——依赖注入(Dependency Injection,DI)现象。
注意:
(1)Angular在创建控制器对象时,会根据形参列表中的每个形参的名称来创建依赖的对象,故控制器声明函数不能声明Angular无法识别的形参名——Angular只提供了这一种依赖注入方式——根据形参名来注入依赖的对象!
(2)若项目JS文件使用了类似yuicompressor等压缩程序,默认会把函数的形参名精简为一个字母的形式,会导致Angular的依赖注入失败!解决办法:
module.controller('控制器名', [
'$scope',
'$interval',
'$http',
function(aaa,bbb,ccc){}
])
["num1", 'num2', 'num3', function add(n1, n2,n3){}]
var num1=10;
var num2=20;
var num5=50;
var num3=30
add(10, 20, 30);
3.可以被注入的对象——所有的service/provider对象都可以被注入
(1)$rootScope:在多个控制器间共享数据的服务
(2)$interval:提供周期性定时器服务
(3)$timeout:
(4)$log:提供五个基本的日志输出服务
(5)$http:提供异步HTTP请求(AJAX)服务
用法: $http({method:'GET', url:'/xx.php'}).
success(fn).
error(fn);
简化版: $http.get('url').success(fn);
$http.post('url', data).success(fn);
(6)$location
4.ng模块中提供的过滤器(filter)
Filter: 把Model数据在显示时以某种特定的格式呈现。
(1)lowercase
语法: {{ 表达式 | lowercase }}
(2)uppercase
语法: {{ 表达式 | uppercase }}
(3)number
语法: {{ 表达式 | number }}
{{ 表达式 | number : 小数位数 }}
(3)currency
语法: {{ 表达式 | currency }}
{{ 表达式 | currency : '货币符号' }}
(3)date
语法: {{ 表达式 | date }} 默认格式: Sep 1, 2015
{{ 表达式 | date : '日期时间格式'}}
5.Web项目中多页应用和单页应用的比较
Mutiple Page Application
Single Page Application
多页应用 |
单页应用(SPA) |
项目中有多个完整的HTML页面 |
整个项目中只有一个完整的HTML页面;其它HTML文件都是HTML片段 |
使用超链接、JS实现页面跳转 |
使用超链接、JS实现“伪跳转” |
所有的页面请求都是同步的——客户端在等待服务器给响应的时候,浏览器中时一片空白 |
所有的“伪页面请求”都是异步请求——客户端在等待下一个页面片段到来时,仍可以显示前一个页面内容——浏览体验更好 |
不便于实现两个页面间切换过场动画 |
很容易实现两个伪页面间的过场切换动画 |
浏览器需要不停的创建完整的DOM树、删除完整的DOM树 |
浏览器只需要创建一个完整的DOM树,此后的伪页面切换其实只是在换某个div中的内容。 |
每个页面都需要加载自己的CSS和JS文件 |
整个项目的CSS和JS文件只需要加载一次 |
手动实现单页应用的步骤:
(1)创建一个完整的HTML页面(如index.html),引入所需要的所有CSS和JS;body中只需要一个伪页面的容器元素,如<div></div>
(2)创建若干个伪HTML页面/模板页面:只需要声明HTML片段
(3)客户端请求完整的HTML页面,同时URL中再追加一个特殊的标记,如http://127.0.0.1/index.html#/start——指定要加载的伪页面的名称
(4)浏览器解析出伪页面名称,查找一个字典,找到该名称对应的模板页面的URL
window.location.hash
#/start => template/start.html
#/m => template/main.html
#/detail => template/productdetail.html
(5)客户端发起异步的AJAX请求,获取模板页面的内容,加载到index.html的伪页面容器中即可
6.AngularJS提供的模块——ngRoute
Route:路由,通过某条线路找到目标内容。
ngRoute模块的用途:就是根据浏览器中URL中的一个特殊的地址标记(形如#/xxx),查找到该标记所对应的模板页面,并异步加载到当前页面的ngView指令中。使用步骤:
(1)创建唯一完整的HTML页面,其中声明一个容器,ngView指令。引入angular.js和angular-route.js
(2)创建多个模板页面(习惯上放在一个特别的目录下,如tpl)
(3)创建Module,声明依赖于ng和ngRoute两个模块。
(4)在Module中配置路由字典。
(5)使用浏览器做测试:
http://IP地址/index.html#/路由地址
7.ngRoute模块中的伪页面跳转
(1)通过超链接跳转
<a href="#/路由地址"> #不能省
(2)通过JS跳转
<button ng-click="jump()"></button>
$scope.jump = function(){
//location.href="2.html" 不能使用多页面应用中的跳转
$location.path('/路由地址'); //#不能有
}