一、angularJS双向数据绑定
利用双向数据绑定,不仅能把数据模型的变化同步到视图上面,还可以利用双向数据绑定的特性来做一些样式上面的控制。
双向数据绑定用处很多,不仅仅是像知识点1中的那个例子,只用花括号来表示。
1.数据模型变化同步到视图
直接用例子来说明:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"> <script src="js/angular.min.js"></script> <script src="js/dataBind_1.js"></script> </head> <body> <div class="panel panel-primary" ng-app="dataInfo" ng-controller="myCtrl"> <div class="panel-heading"> <div class="panel-title">双向数据绑定-数据模型变化同步到视图</div> </div> <div class="panel-body"> <form class="form-horizontal"> <div class="form-group"> <label class="col-md-2 control-label">邮箱:</label> <div class="col-md-10"> <input type="email" class="form-control" placeholder="请输入邮箱" ng-model="userInfo.email"> </div> </div> <div class="form-group"> <label class="col-md-2 control-label">密码:</label> <div class="col-md-10"> <input type="password" class="form-control" placeholder="请输入密码" ng-model="userInfo.password"> </div> </div> <div class="form-group"> <div class="col-md-10 col-md-offset-2"> <div class="checkbox"> <label><input type="checkbox" ng-model="userInfo.autoLogin">自动登录</label> </div> </div> </div> <div class="form-group"> <div class="col-md-10 col-md-offset-2"> <button class="btn btn-default" type="button" ng-click="getData()">获取form表单的值</button> <button class="btn btn-default" type="button" ng-click="setData()">设置form表单的值</button> <button class="btn btn-default" type="button" ng-click="resetData()">重置表单</button> </div> </div> </form> </div> </div> </body> </html>
dataBind_1.js
var dataInfo = angular.module("dataInfo",[]); dataInfo.controller("myCtrl",["$scope", function($scope){ $scope.userInfo = { email:"[email protected]", password:"111111", autoLogin:true }; $scope.getData = function(){ console.log($scope.userInfo); }; $scope.setData = function(){ $scope.userInfo = { email:"[email protected]", password:"111111", autoLogin:false } }; $scope.resetData = function(){ $scope.userInfo = { email:"", password:"", autoLogin:false } }; }]);
效果:
1)点击第一个按钮
2)点击第二个按钮
3)点击第三个按钮
2.样式控制
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="js/angular.min.js"></script> <script src="js/dataBind_2.js"></script> <style type="text/css"> .test-red{ color: red; } .test-green{ color:green; } </style> </head> <body> <div ng-app="myColor" ng-controller="myCtrl"> <p class="test-{{color}}">双向数据绑定-改变CSS样式</p> <button ng-click="setColor()">绿色</button> </div> </body> </html>
dataBind_2.js
var app = angular.module("myColor",[]); app.controller("myCtrl",["$scope", function($scope){ $scope.color = "red"; $scope.setColor = function(){ $scope.color = "green"; } }]);
效果:
----->
通过数据使视图发生变化。上诉变量color如果没有定义,值为none或者undefined,就会出现很多诡异的情况。为了避免这个情况,angularJS定义了ng-class。ng-class可以接收一些表达式。
(1)ng-class
eg:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="js/angular.min.js"></script> <script src="js/ngClass.js"></script> <style type="text/css"> .error{ background: red; } .warning{ background: green; } </style> </head> <body> <div ng-app="ngClass" ng-controller="myClass"> <div ng-class="{error:isError,warning:isWarning}">{{messageTest}}</div> <button ng-click="showError()">showError</button> <button ng-click="showWarning()">showWarning</button> </div> </body> </html>
{error:isError,warning:isWarning} :这是一个表达式,如果isError的值为true,就会用error的样式;如果isWarning的值是true,就会用warning的值。
ngClass.js
var ngClass = angular.module("ngClass",[]); ngClass.controller("myClass",["$scope", function($scope){ $scope.isError = false; $scope.isWarning = false; $scope.showError = function(){ $scope.messageTest = "This is an error!"; $scope.isError = true; $scope.isWarning = false; }; $scope.showWarning = function(){ $scope.messageTest = "Just is a warning!"; $scope.isError = false; $scope.isWarning = true; } }]);
效果:
----->--->
(2)样式的显示和隐藏——ng-show和ng-hide
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="js/angular.min.js"></script> <script src="js/show-hide.js"></script> </head> <body> <div ng-app="ngShow" ng-controller="myShow"> <button ng-click="toggleMenu()">toggle menu</button> <ul ng-show="menuState.show"> <li>JavaScript</li> <li>bootstrap</li> <li>jQuery</li> <li>angularJS</li> </ul> </div> </body> </html>
show-hide.js
var ngShow = angular.module("ngShow",[]); ngShow.controller("myShow",["$scope", function($scope){ $scope.menuState = {show:false}; $scope.toggleMenu = function(){ $scope.menuState.show = !$scope.menuState.show; } } ]);
效果:
------->
ng-hide和ng-show效果相反,用法相同。
二、angularJS模块
1.通过 AngularJS 的 angular.module 函数来创建模块。
模块定义了一个应用程序。
模块是应用程序中不同部分的容器。相当于一个集合。
模块是应用控制器的容器。
控制器通常属于一个模块。
之前的例子充分体现了模块的概念:
(匿名函数)
2.什么时候载入库
对于 HTML 应用程序,通常建议把所有的脚本都放置在 <body> 元素的最底部。
这会提高网页加载速度,因为 HTML 加载不受制于脚本加载。
在多个 AngularJS 实例中,将看到 AngularJS 库是在文档的 <head> 区域被加载。
在实例中,AngularJS 在 <head> 元素中被加载,因为对 angular.module 的调用只能在库加载完成后才能进行。
3.一个完整的项目结构:
node_modules文件夹不用手动添加,在安装基于node.js的工具时系统会自动生成。
app.js : 提供入口点,定义一个module作为启动点,没有太多功能,只是告诉angularJS依赖哪些功能。然后再加一些路由的配置。
三、angularJS路由
1.AJAX的缺陷
(1)ajax的请求不会留下历史记录
(2)用户无法直接通过URL进入应用中的指定界面(保存书签、链接分享给朋友)
(3)ajax对SEO(搜索引擎优化)是个灾难
(4)
2.路由的概念
ngRoute:不同视图之间进行切换
AngularJS 路由允许我们通过不同的 URL 访问不同的内容。
通过 AngularJS 可以实现多视图的单页Web应用(single page web application,SPA)。
通常我们的URL形式为 http://runoob.com/first/page,但在单页Web应用中 AngularJS 通过 # + 标记 实现,例如:
http://runoob.com/#/first http://runoob.com/#/second http://runoob.com/#/third
当我们点击以上的任意一个链接时,向服务端请的地址都是一样的 (http://runoob.com/)。 因为 # 号之后的内容在向服务端请求时会被浏览器忽略掉。 所以我们就需要在客户端实现 # 号后面内容的功能实现。 AngularJS 路由 就通过 # + 标记 帮助我们区分不同的逻辑页面并将不同的页面绑定到对应的控制器上。
(原生路由的缺点:无法进行深层次的嵌套路由。使用angular-UI中的UI-Router就可以解决。)
3.路由的使用
ngRoute并没有在AngularJS的核心包里面,所以在使用的时候,需要引入一个独立的库。
1)在HTML中引入ngRoute
<script src="js/angular.min.js"></script> <script src="js/angular-route.min.js"></script>
2)在应用主模块中,引入ngRoute
3)在模块的config中绑定URL路径与控制器
4.路由规则
在ngRoute中,主要有$route、$routeProvider、$routeParams三个服务项目。
$routeProvider用于在主应用主模块的配置方法中。$route与$routeParams一般常见于控制器中。
(1)$routeProvider
AngularJS 模块的 config 函数用于配置路由规则。通过使用 configAPI,我们请求把$routeProvider注入到我们的配置函数并且使用$routeProvider.whenAPI来定义我们的路由规则。由于$routeProvider是一个服务,根据service的使用建议,我们主要将其当做为工具来使用,所以我们一般直接使用$routeProvider.XXX来调用它的成员方法来实现一定的功能,而不是实例化一个$routeProvider的实例
$routeProvider 为我们提供了 when(path,object) & otherwise(object) 函数按顺序定义所有路由,函数包含两个参数:
- 第一个参数是 URL 或者 URL 正则规则。
- 第二个参数是路由配置对象。
eg:1)index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>route</title> <link href="src/css/test1.css" type="text/css" rel="stylesheet"> <script type="text/javascript" src="bower_components/angular/angular.min.js"></script> <script type="text/javascript" src="bower_components/angular-route/angular-route.min.js"></script> <script type="text/javascript" src="src/js/test1.js"></script> </head> <body> <div class="content" ng-app="myTest"> <nav> <a href="#/login">登录</a> <a href="#/register">注册</a> </nav> <div ng-view=""></div> </div> </body> </html>
(这里使用的是bower.json来加载一些依赖文件,看不懂的朋友可以自己下载文件后再引入到页面中)
2)login.html
<form> <fieldset> <legend>用户登录</legend> <div> <label for="username">用户名:</label> <input type="text" id="username" placeholder="请输入用户名" ng-model="username"> </div> <div> <label for="password">密码:</label> <input type="password" id="password" placeholder="请输入密码" ng-model="password"> </div> <br> <div class="btn"> <button type="reset">重置</button> <button type="submit">确认</button> </div> </fieldset> </form>
3)register.html
<form> <fieldset> <legend>用户注册</legend> <div> <label for="username">用户名:</label> <input type="text" id="username" placeholder="请输入用户名" ng-model="username"> </div> <div> <label for="email">邮箱:</label> <input type="text" id="email" placeholder="请输入邮箱地址" ng-model="email"> </div> <div> <label for="password">密码:</label> <input type="password" id="password" placeholder="请输入密码" ng-model="password"> </div> <div id="result"> <h2>请核对您的输入信息:</h2> <div>用户名:{{username}}</div> <div>邮箱:{{email}}</div> <div>密码:{{password}}</div> </div> <div class="btn"> <button type="reset">重置</button> <button type="submit">确认</button> </div> </fieldset> </form>
4)test1.js
(function (window,angular) { var app = angular.module(‘myTest‘,[‘ngRoute‘]); app.config([‘$routeProvider‘, function($routeProvider){ $routeProvider .when(‘/‘,{template:‘welcome!‘}) .when(‘/login‘,{templateUrl:‘login.html‘}) .when(‘/register‘,{templateUrl:‘register.html‘}) }]); })(window,angular);
(省略css文件)
5.路由配置对象参数说明
(2)$route
$route用于将控制器与视图相连。它观察$location.url(),并且尝试映射路径到一个已经存在的路由定义中。它依赖$location、$routeParams。它主要有如下成员函数:
- reload() 用于重新加载当前的路由,哪怕$location没有改变。调用后,ngView将创建新的Scope等。
它主要有如下事件:
- $routeChangeStart:路由改变之前触发;
- $routeChangeSuccess:路由改变之后触发;
- $routeChangeError:路由改变出错触发;
(3)$routeParams
$routeParams
允许你检索当前路由的参数。主要使用$location
的search()
与path()
方法。----------------------------------------------------------------------------------------------------------------------------
6.UI-Router
UI-Router是Angular-UI提供的客户端路由框架,它解决了原生的ng-route的很多不足:
- 视图不能嵌套。这意味着
$scope
会发生不必要的重新载入。这也是我们在Onboard中引入ui-route
的原因。 - 同一URL下不支持多个视图。这一需求也是常见的:我们希望导航栏用一个视图(和相应的控制器)、内容部分用另一个视图(和相应的控制器)。
UI-Router提出了$state
的概念。一个$state
是一个当前导航和UI的状态,每个$state
需要绑定一个URL Pattern。 在控制器和模板中,通过改变$state
来进行URL的跳转和路由。
(1)引入库文件
引入ui-router库文件之后就不用引入angularJS原生的路由文件了。
(2)在页面中插入
这个表示的是一个视图。
(3)js文件中定义
首先需要注入:
还是运用config函数配置路由规则,只是使用的是$stateProvider,和$urlRouterProvider,不再是$routeProvider.
$stateProvider的用法和$routeProvider非常相似,只是它的方法名是state,而不是when。
在index.html中:
语法:[email protected] (记住就可以了)
----------------------------------------------------------------------------------------------------------------------------
!!!在页面中设置点击跳转路径:
<a ui-sref=”task”></a> 其中ui-sref的值必须为state的名称。
!!!ui-router中传递参数的三种方式:
@1.
.state(‘task’,{
url: ’task/{id}’
})
@2.
.state(‘task’,{
url: ’task/:id’
})
@3
.state(‘task’,{
url: ’task’,
params:{
id:{value:42}
}
})
!!!在js中可以通过$stateParams获得参数id
!!!在页面中设置点击跳转路径:
<a ui-sref=”task({id:task.id})”></a> 其中ui-sref的值必须为state的名称。
!!!页面导航栏被选中样式:
<a ui-sref-active=”selected”></a>
在css中定义selected的样式即可。