AngularJS

作者: 帅哥_刷哥 | 来源:发表于2017-09-29 10:05 被阅读64次

    第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
    

    相关文章

      网友评论

          本文标题:AngularJS

          本文链接:https://www.haomeiwen.com/subject/lrqmextx.html