欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

AngularJS

程序员文章站 2022-07-02 18:54:48
...

第1章 介绍

js尽量写到界面的最后

1.0 介绍
    AngularJS是一款由Google公司开发维护的前端MVC框架,其克服了HTML在构建应用上的诸多不足,从而降低了开发成本提升了开发效率。
1.1 特点
    AngularJS与我们之前学习的jQuery是有一定的区别的,jQuery更准确来说只一个类库(类库指的是一系列函数的集合)以DOM做为驱动(核心),
    而AngularJS则一个框架(诸多类库的集合)以数据和逻辑做为驱动(核心)。
    框架对开发的流程和模式做了约束,开发者遵照约束进行开发,更注重的实际的业务逻辑。
    AngularJS有着诸多特性,最为核心的是:模块化、双向数据绑定、语义化标签、依赖注入等。
    与之类似的框架还有BackBone、KnockoutJS、Vue、React等。
1.2 下载
    1、通过AngularJS官网下载,不过由于国内特殊的国情,需要*才能访问。
        https://angularjs.org/
    2、通过npm下载,npm install angular
    3、通过bower下载,bower install angular
1.3 体验AngularJS
    <!-- 引入angularJS框架 -->
    <script src="./libs/angular.min.js"></script>
    <!--  -->
    <body ng-app>
        <!-- 把输入框中的内容放到 msg变量中 -->
        <input type="text" ng-model="msg">
        <!-- 动态的把msg变量的值拿出展示,只要msg的值发生变化就会动态获取 -->
        <h2>{{msg}}</h2>
    </body>
1.4 MVC
    MVC是一种开发模式,由模型(Model)、视图(View)、控制器(Controller)3部分构成,采用这种开发模式为合理组织代码提供了方便、降低了代码间的耦合度、功能结构清晰可见。
        模型(Model)一般用来处理数据(读取/设置),一般指操作数据库。
        视图(View)一般用来展示数据,比如通过HTML展示。
        控制器(Controller)一般用做连接模型和视图的桥梁。
    通过ThinkPHP来演示后端MVC的执行流程,其重点在于理解。
    MVC更多应用在后端开发程序里,后被引入到前端开发中,由于受到前端技术的限制便有了一些细节的调整,进而出现了很多MVC的衍生版(子集)如MVVM、MVW、MVP、MV*等。
    注:做为初学可以不必过于在意这些概念。

第2章 模块化

2.0 介绍
    使用AngularJS构建应用(App)时是以模块化(Module)的方式组织的,即将整个应用划分成若干模块,每个模块都有各自的职责,最终组合成一个整体。
    采用模块化的组织方式,可以最大程度的实现代码的复用,可以像搭积木一样进行开发。
2.1 定义应用View视图
    <!-- 指定模块 -->
    <div class="box" ng-app="App">
        !-- 指定控制器 -->
        <div ng-controller="DemoContoller"></div>
    </div>
    
    一定要先有模块,后有控制器
    一个页可以有多个模块,但是不能互想嵌套
    一般只会有一个
    
2.2 定义模块
    AngularJS提供了一个全局对象angular,在此全局对象下存在若干的方法,其中angular.module()方法用来定义一个模块。
    注:应用(App)其本质也是一个模块(一个比较大的模块)。
    代码:
        var App = angular.module('App', []);
            App就是新创建的模块,这个模块又是一个对象
            在此对象下又有N多方法,可以实现具体业务逻辑
            App 就是div中的ng-app中的内容
    
2.3 定义控制器
    控制器(Controller)作为连接模型(Model)和视图(View)的桥梁存在,所以当我们定义好了控制器以后也就定义好了模型和视图。
    模型(Model)数据是要展示到视图(View)上的,所以需要将控制器(Controller)关联到视图(View)上
    通过为HTML标签添加ng-controller属性并赋值相应的控制器(Controller)的名称,就确立了关联关系。
    代码:
        App.controller('DemoContoller', ['$scope', function ($scope) {}]);
            $scope 是一个空对象{},此对象就是Model
            DemoContoller 是div中的ng-controller属性的值

第3章 指令

3.0 说明
    HTML在构建应用(App)时存在诸多不足之处,AngularJS通过扩展一系列的HTML属性或标签来弥补这些缺陷,
    所谓指令就是AngularJS自定义的HTML属性或标签,这些指令都是以ng-做为前缀的,例如ng-app、ng-controller、ng-repeat等。
3.1 内置指令(view(html)中的ng指令)
    ng-app="Demo" 模块名称,指定应用根元素,至少有一个元素指定了此属性。
    ng-controller="StarsController" 控制器名称,指定控制器
    ng-init="name='shuaige';age=10" 用于初始化属性值,相当于$scope.name='shuaige';$scope.age=10;
    ng-repeat="str in arr" 遍历数组
    ng-switch-when="java" 用来判断某个变量中的值是否是java,跟ng-repeat一起使用可以判断当前对象的值是否是Java。
    ng-switch on 选择判断结构。跟ng-switch-when一起使用。<div ng-switch on="type"><div ng-switch-when="java">当type的值是Java时显示</div></div>
    ng-show="0" 用来显示或隐藏内容(元素实际存在),1显示,0隐藏
    ng-hide="1" 用来显示或隐藏内容(元素实际存在),1隐藏,0显示
    ng-if="1" 用来控制元素是否存在(元素可能不存在),1存在,0不存在
    ng-src="{{path}}" 用来添加src路径。在angular中要使用此指令添加路径,否则会有页面图片找不到到页面从新刷新的小问题。
    ng-href="{{path}}" 用来添加href路径
    ng-class="{red: true}" 用来控制类名。用来添加css中的class样式
        ng-class="{active: type == 'local'}" 用$scope中的type变量的值来控制active这个类是否添加还是移除。
    ng-include 引入模板 <body ng-app="App"><div ng-include="'./header.html'"></div><script>var App = angular.module('App', []);</script></body>
    ng-disabled="1" 表单禁用。用来控制元素是否可用,1不可用,0可用
    ng-readonly="1" 表单只读。用来控制元素是否只读,1只读,0可修改
    ng-checked="1" 单/复选框表单选中。用来控制多选框元素是否选中,1选中,0未选中
    ng-selected="1" 下拉框表单选中。用来控制下拉框元素是否选中,1选中,0未选中
    ng-bind="name" 用来绑定model模型($scope)中的name属性。可以获取name属性的值。跟{{name}}效果一样
    ng-cloak 用来解决页面刷新速度过快导致的闪动问题(可以看到{{}}这个括号),用法<li ng-cloak>{{name}}{{age}}</li>
    ng-bind-template 绑定多个数据,用法<li ng-bind-template="{{name}}{{age}}"></li>
    ng-model="msg" 绑定数据。要实现数据从视图向模型传递需要借助于表单元素,相当于$scope.msg
    ng-click="show()" 单击。用来调用$scope.show = function(){} 这个show方法
        ng-click="show('local')" 调用$scope.switch = function(type){} 这个方法。type就等于local。
    ng-dblclick="double()" 双击。用来调用$scope.double = function(){}这个double方法
    ng-blur="blur()" 失去焦点。用来调用$scope.blur = function(){} 这个blur方法
    ng-mouseout="mouseout()" 鼠标移除事件。用来调用$scope.mouseout = function(){}这个mouseout方法


<h1 ng-cloak>{{name}}</h1>
<h1 ng-bind="name"></h1>
<h1 ng-bind-template="{{name}}"></h1>
<h1>{{aa}}</h1>
<h1>{{bb}}</h1>
<ul>
    <li ng-repeat="str in arrs">{{str}}</li>
</ul>
<ul>
    <li ng-repeat="student in students">{{student.name}}-{{student.age}}</li>
</ul>
<input type="text" ng-if="type"/>
<input type="text" ng-show="type"/>
<input type="text" ng-hide="type"/>
<img ng-src="./img/01.jpg">
<a ng-href="{{path}}">atest</a><br/><br/><br/><br/>
<div ng-include="'./views/one.html'"></div>
<input type="text" ng-disabled="type" />
<input type="text" ng-readonly="type" />
<input type="checkbox" name="sex" value="男" ng-checked="type" />男
<input type="checkbox" name="sex" value="女" ng-checked="type"/>女
<input type="radio" name="gendar" value="男"/>男
<input type="radio" name="gendar" value="女"  ng-checked="type"/>女
<select>
    <option>中国</option>
    <option ng-selected="type">美国</option>
</select>
<input type="text" ng-model="msg"/>
<h1 ng-bind="msg" ng-class="{red:type}"></h1>

<ul ng-switch="msg">
    <li ng-switch-when="shuaige">shuaige</li>
    <li ng-switch-when="shuaige2">shuaige2</li>
</ul>

<ul ng-repeat="str in arrs" ng-switch="str">
    <li ng-switch-when="java">java技术</li>
    <li ng-switch-when="css">css技术</li>
    <li ng-switch-when="js">js技术</li>
</ul>
<button ng-click="click()">click</button>
<h1 ng-dblclick="dbclick1()">dbclick</h1>
<input type="text" ng-blur="blur()" />
<p ng-mouseout="mouseout()">这是一块区域</p>




3.2 自定义指令
    AngularJS允许根据实际业务需要自定义指令,通过angular全局对象下的directive方法实现。
        // E element 是一个元素  <tag></tag>
        // A attribute 是一个属性 <div tag></div>
        // C class 是一个类 <div class="tag"></div>
        // M mark replace 必须为true  <!-- directive:tag -->备注
    代码1:
        <div tag></div>
        var App = angular.module('App', []);
        App.directive('tag', function () {
            return {
                    restrict: 'EA',
                    template: '<p>hello shuaige</p>'
                }
        });
        界面会显示hello shuaige
    代码2:要用localhost访问,否则会显示报错
        <div tag></div>
        var App = angular.module('App', []);
        App.directive('tag', function () {
            return {
                    restrict: 'EA',
                    templateUrl: './lists.html'
                }
        });
        界面会显示lists.html中的内容
    代码3:要用localhost访问,否则会显示报错
        <div tag></div>
        var App = angular.module('App', []);
        App.directive('tag', function () {
            return {
                    restrict: 'EA',
                    templateUrl: './lists.html',
                    replace: true
                }
        });
        界面会显示lists.html中的内容,但是外层的标签会去掉。
3.3 具体使用
    $scope 是一个空对象{},此对象就是Model
        //普通字符串
        $scope.name = '李振杰';
            //view中取值 {{name}}
        //数组
        $scope.courses = ['MVC','指令','模块化']
            //view中取值 <li ng-repeat="(key, course) in courses">第{{key}}天:{{course}}</li>
                ng-repeat="(key, course) in courses"是就遍历courses数组
                    (key,course) : key是下标,course是游标代表数组当前位置的值。
                    取值key是{{key}}
                    取值course是{{course}}
        //数组
        $scope.stars = [{name: '刘德华', sex: '男', age: 62},{name: '王力宏', sex: '男', age: 40}];
            //view中取值 
                <tr ng-repeat="star in stars">
                    <td>{{star.name}}</td>
                    <td>{{star.sex}}</td>
                    <td>{{star.age}}</td>
                </tr>   
                ng-repeat="star in stars" 是遍历 stars 数组,数组当前位置的变量名为star
                {{star.name}},{{star.sex}},{{star.age}} 是获取当前变量中的name,sex,age属性的值。

        //数组
        $scope.names = [];
        //往数组中添加一条数据
        $scope.names.push('shuaige');
        //从数组中取出一条数据,并且从数组中移除
        $scope.names.splice(start,length);

第4章 数据绑定

4.0 说明
    AngularJS是以数据做为驱动的MVC框架,所有模型(Model)里的数据经由控制器(Controller)展示到视图(View)中。
    所谓数据绑定指的就是将模型(Model)中的数据与相应的视图(View)进行关联,分为单向绑定和双向绑定两种方式。
4.1 单向绑定
    单向数据绑定是指将模型(Model)数据,按着写好的视图(View)模板生成HTML标签,然后追加到DOM中显示.

4.2 双向绑定
    双向绑定则可以实现模型(Model)数据和视图(View)模板的双向传递
    <input type="text" ng-model="msg">

4.3 相关指令
    在AngularJS中通过“{{}}”和ng-bind指令来实现模型(Model)数据向视图模板(View)的绑定,
    模型数据通过一个内置服务$scope来提供,这个$scope是一个空对象,
    通过为这个对象添加属性或者方法便可以在相应的视图(View)模板里被访问。
        注:“{{}}”是ng-bind的简写形式,其区别在于通过“{{}}”绑定数据时会有“闪烁”现象,
            添加ng-cloak也可以解决“闪烁”现象,通过ng-bind-template可以绑定多个数据。

    ng-model 实现视图(View)模板向模型(Model)数据的绑定。
    ng-init 初始化模型(Model)也就是$scope
    
    AngularJS对事件也进行了扩展,无需显式的获取DOM元素便可以添加事件,易用性变的更强。
    通过在原有事件名称基础上添加ng-做为前缀,然后以属性的形式添加到相应的HTML标签上即可。
    如ng-click、ng-dblclick、ng-blur等。

    ng-repeat可以将数组或对象数据迭代到视图模板中,ng-switch、on、ng-switch-when可以对数据进行筛选。

第5章 作用域

5.0 说明
    通常AngularJS中应用(App)是由若干个视图(View)组合成而成的,而视图(View)又都是HTML元素,并且HTML元素是可以互相嵌套的,
    另一方面视图都隶属于某个控制器(Controller),进而控制器之间也必然会产生嵌套关系。
    每个控制器(Controller)又都对应一个模型(Model)也就是$scope对象,不同层级控制器(Controller)下的$scope便产生了作用域。
5.1 根作用域
    一个AngularJS的应用(App)在启动时会自动创建一个根作用域$rootScope,这个根作用域在整个应用范围(ng-app所在标签以内)都是可以被访问到的。
    <div ng-app="App" ng-init="name='shuaige';age=20"></div>
    ng-app 所在元素就是应用的根元素
    ng-init 为$rootScope添加数据
5.2 子作用域
    通过ng-controller指令可以创建一个子作用域,新建的作用域可以访问其父作用域的数据。
    $scope.name = '帅哥';

第6章 过滤器

6.0 说明
    在AngularJS中使用过滤器格式化展示数据,在“{{}}”中使用“|”来调用过滤器,使用“:”传递参数。
6.1 内置过滤器
    currency将数值格式化为货币格式
        {{price|currency:'¥'}}
        $scope.price = 11.11;
    date日期格式化,年(y)、月(M)、日(d)、星期(EEEE/EEE)、时(H/h)、分(m)、秒(s)、毫秒(.sss),也可以组合到一起使用。
        {{now|date:'yyyy/MM/dd hh:mm:ss'}}
        $scope.now = new Date;
    filter在给定数组中选择满足条件的一个子集,并返回一个新数组,其条件可以是一个字符串、对象、函数
        {{items|filter:'s'}}
        $scope.items = ['html', 'css', 'js']; 从中挑出包含s的数据显示在界面
        {{students|filter:{age: 16} }}
        $scope.students = [{name: '小红', age: 16},{name: '小明', age: 16},{name: '小米', age: 10}]; 从中挑出age等于16的数据
    json将Javascrip对象转成JSON字符串
        {{students|json}}
        $scope.students = [{name: '小红', age: 16},{name: '小明', age: 16},{name: '小米', age: 10}]; 会显示json字符串
    limitTo取出字符串或数组的前(正数)几位或后(负数)几位
        {{items|limitTo:-1}}
        $scope.items = ['html', 'css', 'js']; 页面只显示js
    lowercase将文本转换成小写格式
        {{str|lowercase}}
        $scope.str = 'hello Angular'; 小写展示数据
    uppercase将文本转换成大写格式
        {{str|uppercase|limitTo:3}}
        $scope.str = 'hello Angular'; 从开始取3位字符,大写展示数据
    number数字格式化,可控制小位位数
        {{num|number:2}}
        $scope.num = '10.2365'; 取小数点两位显示
    orderBy对数组进行排序,第2个参数可控制方向
        {{items|orderBy: '':true}}
        $scope.items = ['html', 'ass', 'js']; 排序,false按照自然顺序正向排序,true按照自然顺序逆向排序
        {{students|orderBy: 'age': false}}
        $scope.students = [{name: '小红', age: 16},{name: '小明', age: 9},{name: '小米', age: 10}];//按照age排序。false按照自然顺序正向排序,true按照自然顺序逆向排序
6.2 自定义过滤器
    除了使用AngularJS内建过滤器外,还可以根业务需要自定义过滤器,通过模块对象实例提供的filter方法自定义过滤器。
        //自定义过滤器
        App.filter('shuaige', function () {
            return function (input) {
                return 'hello ' + input;
            }
        });
        //使用过滤器
        {{info|shuaige}}
        $scope.info = 'shuaige';

第7章 依赖注入

7.0 说明
    AngularJS采用模块化的方式组织代码,将一些通用逻辑封装成一个对象或函数,实现最大程度的复用,这导致了使用者和被使用者之间存在依赖关系。 
    所谓依赖注入是指在运行时自动查找依赖关系,然后将查找到依赖传递给使用者的一种机制。
    常见的AngularJS内置服务有$http、$location、$timeout、$rootScope等
7.1 推断式注入
    没有明确声明依赖,AngularJS会将函数参数名称当成是依赖的名称。
    这种方式会带来一个问题,当代码经过压缩后函数的参数被压缩,这样便会造成依赖无法找到。
    AngularJS 内置一些具有特殊功能的“模块”
    开发者在开发的时候可以直接使用这些“模块”
    <div class="box" ng-controller="DemoController"></div>
    App.controller('DemoController', function ($scope, $http) {});
7.2 行内注入
    以数组形式明确声明依赖,数组元素都是包含依赖名称的字符串,数组最后一个元素是依赖注入的目标函数。
    推荐使用这种方式声明依赖
    <div ng-controller="DemoController"></div>
    App.controller('DemoController', ['$scope', '$http', function (abc, bcd) {}]);

第8章 服务

8.0 说明
    服务是一个对象或函数,对外提供特定的功能
8.1 内建服务
    1.$location是对原生Javascript中location对象属性和方法的封装
        App.controller('DemoController', ['$scope', '$location', function($scope, $location) {
            $scope.absUrl = $location.absUrl();//绝对地址
            $scope.url = $location.url();//锚点#后面的内容
            $scope.host = $location.host();//地址
            $scope.search = $location.search();
            $scope.hash = $location.hash();
            $scope.protocol = $location.protocol();//协议
            $scope.port = $location.port();//端口号
        }]);
    2.$timeout&$interval对原生Javascript中的setTimeout和setInterval进行了封装。
        App.controller('DemoController', ['$scope', '$timeout', '$interval',function ($scope, $timeout, $interval) {
            $timeout(function () {
                $scope.msg = '执行了';
            }, 3000);
            var timer = $interval(function () {
                $scope.now = new Date;
            }, 1000);
            $scope.stop = function () {
                $interval.cancel(timer);
            }
        }]);
    3.$filter在控制器中格式化数据
        App.controller('DemoController', ['$scope', '$filter', function ($scope, $filter) {
            // $filter是九种过滤器中任何一个
            $scope.price = 11.11;
            var currency = $filter('currency');
            $scope.price = currency($scope.price);
            $scope.str = 'hello angular';
            var uppercase = $filter('uppercase');
            $scope.str = uppercase($scope.str);
            $scope.str1 = $filter('limitTo')($scope.str, 2);
        }]);
    4.$log打印调试信息
        App.controller('DemoController', ['$log', function ($log) {
            $log.info('普通信息');
            $log.warn('警告信息');
            $log.error('错误信息');
            $log.log('打印信息');
            $log.debug('调试信息');
        }]);
    5.$http用于向服务端发起异步请求
        $http 本质是对XMLHttpRequest对象封装
        App.controller('DemoController', ['$scope', '$http', '$log', function ($scope, $http, $log) {
            $http({
                url: 'example.php',
                method: 'post',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                params: { // get 参数
                    name: 'itcast',
                    sex: '男'
                },
                data: { // post 传参
                    age: 10
                }
            }).success(function (info) {
                $log.info(info);// info 就是返回的数据
            });
        }]);
        App.controller('StarController', ['$http', '$scope', '$log', function ($http, $scope, $log) {
            $scope.getData = function () {
                $http({
                    url: './stars.php',
                    method: 'get'
                }).success(function (info) {
                    $scope.stars = info;
                });
            }
        }]);
        $http跨域
        App.controller('DemoController', ['$http', '$scope', function ($http, $scope) {
            $http({
                url: 'jsonp.php?a=JSON_CALLBACK',
                method: 'jsonp' // 采用JSONP方式
            }).success(function (info) {
                console.log(info);
            });
        }]);
        请求一下百度天气http://api.map.baidu.com/telematics/v3/weather?callback=JSON_CALLBACK
        Weather.controller('WeatherController', ['$scope', '$http', function ($scope, $http) {
            $http({
                url: 'http://api.map.baidu.com/telematics/v3/weather',
                method: 'jsonp',
                params: {
                    location: '北京',
                    output: 'json',
                    ak: '0A5bc3c4fb543c8f9bc54b77bc155724',
                    callback: 'JSON_CALLBACK'
                }
            }).success(function (info) {
                $scope.weatherData = info.results[0].weather_data;
            });


        }]);
    6.同时还支持多种快捷方式如$http.get()、$http.post()、$http.jsonp
8.2 自定义服务
    通过上面例子得知,所谓服务是将一些通用性的功能逻辑进行封装方便使用,AngularJS允许将自定义服务。
    在介绍服务时曾提到服务本质就是一个对象或函数,所以自定义服务就是要返回一个对象或函数以供使用。
    1.factory方法
        //定义一个名叫showTime的服务
        App.factory('showTime', ['$filter', function ($filter) {
            var now = new Date();
            var date = $filter('date');
            return {
                now: date(now, 'y-M-d H:m:s')
            }
        }]);
        //使用服务
        App.controller('DemoController', ['$scope', 'showTime', function($scope, showTime) {
            $scope.now = showTime.now;
        }]);
        App.controller('DemoController', ['$scope', '$http', 'showTime', function ($scope, $http, showTime) {}]);
    2.service方法
        App.service('showTime', ['$filter', function($filter) {
            var now = new Date();
            var date = $filter('date');
            this.now = date(now, 'y-M-d H:mm:ss');
        }]);

        App.controller('DemoController', ['$scope', 'showTime', function($scope, showTime) {
            $scope.now = showTime.now;
        }]);
    3.value方法定义常量
        //本质上一个服务
        //从表现形式上是一个常量
        //常量就是不变的值与变对量相对应
        App.value('author', 'shuaige');
        App.controller('DemoController', ['$scope', 'author', function($scope, author) {
            $scope.author = author;
        }]);

第9章 模块加载

9.0 说明
    AngularJS模块可以在被加载和执行之前对其自身进行配置。我们可以在应用的加载阶段配置不同的逻辑。
    执行流程
        1.启动阶段
            开始->浏览器解析DOM树->遇到angular.js停止解析,开始执行脚本->angular监听到DOMContent Loaded事件->启动angular应用
        2.初始化阶段
            查找模块依赖->寻找ng-app指令->初始化必要组件($injector/$complie/$rootScope)->配置和运行->开始解析DOM树
        3.编译链接阶段
            $complie遍历DOM树,搜集指令->执行每个指令的complie函数->处理DOM转换,编译模板->调用链接函数,生成实时视图
        4.运行阶段
            等待事件触发,执行$digest循环->检测到变化,调用$watch函数->再次执行$digest循环,直到没有变化->结束
9.1 配置块
    通过config方法实现对模块的配置,AngularJS中的服务大部分都对应一个“provider”,用来执行与对应服务相同的功能或对其进行配置。
    比如$log、$http、$location都是内置服务,相对应的“provider”分别是$logProvider、$httpProvider、$locationPorvider。
    
    //配置一个服务
    App.config('$logProvider',function($logProvider){});
    //配置多个服务
    App.config(['$logProvider', '$filterProvider', function ($logProvider, $filterProvider) {
        // 禁用debug功能 $log.debug();
        $logProvider.debugEnabled(false);

        // 默认9个过滤器,通过配置可以新增一些过滤器
        $filterProvider.register('capitalize', function () {
            // 新增一个过滤器
            return function (input) {
                return input[0].toUpperCase() + input.slice(1);
            }
        });
    }]);
    
    
9.2 运行块
    服务也是模块形式存在的对且对外提供特定功能,前面学习中都是将服务做为依赖注入进去的,然后再进行调用,
    除了这种方式外我们也可以直接运行相应的服务模块,AngularJS提供了run方法来实现。
    不但如此,run方法还是最先执行的,利用这个特点我们可以将一些需要优先执行的功能通过run方法来运行,
    比如验证用户是否登录,未登录则不允许进行任何其它操作。
    注:此知识点意在了解AngularJS的加载机制。
    
    App.run(['$http',function ($http) {
        // 直接调用$http
        $http({
            url: 'example.php',
            method: 'get'
        });
    }]);

    App.run(['$http', '$rootScope', function ($http, $rootScope) {
        // 直接调用$http
        $http({
            url: 'example.php',
            method: 'get'
        });
        // 根作用域
        $rootScope.name = '帅哥';
    }]);

第10章 路由

10.0  说明
    一个应用是由若个视图组合而成的,根据不同的业务逻辑展示给用户不同的视图,路由则是实现这一功能的关键。
    angularjs默认支持restful接口
10.1  SPA   
    SPA(Single Page Application)指的是通单一页面展示所有功能,通过Ajax动态获取数据然后进行实时渲染,
    结合CSS3动画模仿原生App交互,然后再进行打包(使用工具把Web应用包一个壳,这个壳本质上是浏览器)变成一个“原生”应用。
    在PC端也有广泛的应用,通常情况下使用Ajax异步请求数据,然后实现内容局部刷新,局部刷新的本质是动态生成DOM,
    新生成的DOM元素并没有真实存在于文档中,所以当再次刷新页面时新添加的DOM元素会“丢失”,通过单页面应可以很好的解决这个问题。
10.2  路由
    在后端开发中通过URL地址可以实现页面(视图)的切换,但是AngularJS是一个纯前端MVC框架,
    在开发单页面应用时,所有功能都在同一页面完成,所以无需切换URL地址(即不允许产生跳转),
    但Web应用中又经常通过链接(a标签)来更新页面(视图),当点击链接时还要阻止其向服务器发起请求,
    通过锚点(页内跳转)可以实现这一点。
    
    1.实现单页面应用需要具备:
        a、只有一页面
        b、链接使用锚点
        通过上面的例子发现在单一页面中可以能过hashchange事件监听到锚点的变化,进而可以实现为不同的锚点准不同的视图,单页面应用就是基于这一原理实现的。
        AngularJS对这一实现原理进行了封装,将锚点的变化封装成路由(Route),这是与后端路由的根本区别。
        在1.2版前路由功能是包含在AngularJS核心代码当中,之后的版本将路由功能独立成一个模块,下载angular-route.js
        
    spa页面应用特点
        把多个项目链接放到同一个页面,不产生页面跳转
        把若干功能集成到一个页面
        动态生成数据,通过ajax异步获取
        为了增强用户体验
        可以提升性能
        仿制手机app的交互
        锚点是前端的路由
        hashchange监听锚点变化,绑定给window对象。
        
    路由js写法
        <!-- 导航菜单  js写法 -->
        <ul>
            <li class="active">
                <a href="#index">Index</a>
            </li>
            <li>
                <a href="#introduce">Introduce</a>
            </li>
            <li>
                <a href="#contact">Contact Us</a>
            </li>
        </ul>
        <!-- 内容 -->
        <div class="content">
            Index Page
        </div>
        // 监听锚点变化然后发送请求
        // hashchange事件可以监听锚点变化
        window.addEventListener('hashchange', function () {
            // 获取锚点
            var hash = location.hash;
            // 处理#
            hash = hash.slice(1);
            // 实例对象
            var xhr = new XMLHttpRequest;
            // 将锚点做为参数传递给服务端进处理
            xhr.open('get', '10-01.php?hash=' + hash);
            xhr.send(null);
            xhr.onreadystatechange = function () {
                if(xhr.readyState == 4 && xhr.status == 200) {
                    var result = xhr.responseText;
                    // 将返回结果添加到页面
                    document.querySelector('.content').innerHTML = result;
                }
            }
        });
        
    
    
        
10.2.1  使用
    1.引入angular-route.js
    2.实例化模块(App)时,当成依赖传进去(模块名称叫ngRoute)
    3.配置路由模块
    4.布局模板 - 通过ng-view指令布局模板,路由匹配的视图会被加载渲染到些区域
    
    路由angularjs写法
        <!-- 导航菜单 -->
        <ul>
            <li class="active">
                <a href="#/index">Index</a>
            </li>
            <li>
                <a href="#/introduce">Introduce</a>
            </li>
            <li>
                <a href="#/contact">Contact Us</a>
            </li>
            <li>
                <a href="#/list">List</a>
            </li>
        </ul>
        <!-- 内容 -->
        <div class="content">
            <!-- 占位符 -->
            <div ng-view></div>
        </div>
        <!-- AngularJS核心框架 -->
        <script src="./libs/angular.min.js"></script>
        <!-- 路由模块理解成插件 -->
        <script src="./libs/angular-route.js"></script>
        <script>
            // 依赖ngRoute模块
            var App = angular.module('App', ['ngRoute']);
            // 需要对路由模块进行配置,使其正常工作
            App.config(['$routeProvider', function ($routeProvider) {
                $routeProvider.when('/index', {
                    // template: '<h1>index Pages!</h1>',
                    templateUrl: './abc.html'
                })
                .when('/introduce', {
                    template: '<h1>introduce Pages!</h1>'
                })
                .when('/contact', {
                    // template: '<h1>contact US Pages!</h1>',
                    templateUrl: './contact.html',
                    controller: 'ContactController' // 定义控制器
                })
                .when('/list', {
                    templateUrl: './list.html', // 视图模板
                    controller: 'ListController' // 定义控制器 这个控制器就是控制list.html的
                })
                .otherwise({
                    redirectTo: '/index'
                });
            }]);
            // 列表控制器
            App.controller('ListController', ['$scope', '$http', function ($scope, $http) {
                // 模型数据
                $http({
                    url: '10-02.php',
                }).success(function (info) {
                    $scope.items = info;
                });
            }]);
            App.controller('ContactController', ['$scope', '$http', function ($scope, $http) {
                $http({
                    url: 'contact.php'
                }).success(function (info) {
                    $scope.content = info;
                });
            }]);
        </script>
    
10.2.1  路由参数
    1.提供两个方法匹配路由,分别是when和otherwise,when方法需要两个参数,otherwise方法做为when方法的补充只需要一个参数,其中when方法可以被多次调用。
    2.第1个参数是一个字符串,代表当前URL中的hash值
    3.第2个参数是一个对象,配置当前路由的参数,如视图、控制器等
        a、template 字符串形式的视图模板
        b、templateUrl 引入外部视图模板
        c、controller 视图模板所属的控制器
        d、redirectTo跳转到其它路由
    4.获取参数,在控制中注入$routeParams可以获取传递的参数
        a)url问号传参数
        b)占位符传参
    
    代码:
        <!-- AngularJS核心框架 -->
        <script src="./libs/angular.min.js"></script>
        <!-- 路由模块理解成插件 -->
        <script src="./libs/angular-route.js"></script>
        <script>
            // 依赖ngRoute模块
            var App = angular.module('App', ['ngRoute']);
            // 需要对路由模块进行配置,使其正常工作
            App.config(['$routeProvider', function ($routeProvider) {
                $routeProvider.when('/index/:id/:page/:p', {
                    templateUrl: 'abc.html',
                    controller: 'IndexController'
                })
                .otherwise({
                    redirectTo: '/index'
                });
            }]);
            // 提供了一个专门负责获取参数的一个服务$routeParams
            App.controller('IndexController', ['$scope', '$http', '$routeParams', function ($scope, $http, $routeParams) {
                $scope.content = '练习路由功能';
                console.log($routeParams);
            }]);
        </script>
        
        <!--
            后端会说明需要什么样的参数
            需要一个类型 ID:1,2,3,4
            1表示流行 2表示华语 3表示欧美 4表示日韩
        -->
        <nav>
            <a href="#/1"></a>
            <a href="#/2"></a>
            <a href="#/3"></a>
            <a href="#/4"></a>
        </nav>

        Music.config(['$routeProvider',function($routeProvider){
            $routeProvider.when("/:id",{
                templateUrl:'./views/list.html',
                controller:'ListController'
            });
        }]);
        Music.controller('ListController',['$scope','$http','$routeParams',function($scope,$http,$routeParams){
            var id = $routeParams.id;//获取地址上的参数
            $http({
                url:'./api/list.php',
                method:'get',
                params:{type:id}//将获取到的参数传给后端
            }).success(function(info){
                console.log(info);
            });
        }]);

第11章 其它

11.1    jQuery
    在没有引入jQuery的前提下AngularJS实现了简版的jQuery Lite,通过angular.element不能选择元素,但可以将一个DOM元素转成jQuery对象,
    如果引提前引入了jQuery则angular.element则完全等于jQuery。
    
    angular.element() 方法可以将一个原生DOM对象转成jquery对象
    但是angularJS 只是实现了jquery对象部分方法
    // 原生DOM对象
    var box = document.querySelector('.box');
    var btn = document.querySelector('button');
    // 转成jQuery对象
    box = angular.element(box);
    btn = angular.element(btn);
    btn.on('click', function () {
        box.css('color', 'red');
    });
    
    
11.2    bower
    基于NodeJS的一个静态资源管理工具,由twitter公司开发维,解决大型网站中静态资源的依赖问题。
    1、依赖NodeJS环境和git工具。
    2、npm install -g bower安装bower
    3、bower search 查找资源信息
    4、bower install  安装(下载)资源,通过#号可以指定版本号
    5、bower info 查看资源信息
    6、bower uninstall 卸载(删除)资源
    7、bower init初始化,用来记录资源信息及依赖。
    
    步骤:
        node -v 安装node.js
        npm -vv
        npm install -g brower / npm install -g brower --registry=https://registry.npm.taobao.org
        
        打开git工具/在项目目录下安装jQuery或者其它
        brower install jquery / brower install jquery#1.7.2
        brower info jquery 
        brower uninstall jquery 
        brower init / brower init -config.interactive

其它

angularjs 广播
$scope.$on
$scope.$broadcast
$scope.emit