AngularJS

作者: 欢欣的膜笛 | 来源:发表于2021-02-20 18:03 被阅读0次

    AngularJS 是什么

    • 概念:
      • AngularJS主要用于构建单页面Web应用,是一种构建动态Web应用的结构化框架。
    • 核心功能:
      • 模块化、双向数据绑定、语义化标签、依赖注入(行内注入、推断式注入)、$http等。

    AngularJS模块(使用angular.module()方法来声明模块)

    • 优点:
      • 保持全局命名空间的清洁;
      • 编写测试代码更容易,并能保持其清洁,以便更容易找到互相隔离的功能;
      • 易于在不同应用间复用代码;
      • 使应用能够以任意顺序加载代码的各个部分。

    实现模型-视图的双向绑定

    • 数据绑定就是数据与视图的一一对应关系,模板引擎为单向绑定,AngularJS为双向绑定
    • 通过model建立数据模型,视图上的数据就会对应存储在angular程序里,视图上的数据变化会同步到model,model的数据改变也会同步到视图
    • 脏检查机制(dirty-checking)是实现双向数据绑定的重要基础。
    • 脏检查机制:Angular将双向绑定转换为一堆watch表达式,然后递归这些表达式检查是否发生过变化,如果变了则执行相应的watcher函数(指view上的指令,如ng-bind,ng-show等或是{{}})。等到model中的值不再发生变化,也就不会再有watcher被触发,一个完整的digest循环就完成了。
    • 脏检查机制的触发:Angular中在view上声明的事件指令,如:ng-click、ng-change等,会将浏览器的事件转发给scope上相应的model的响应函数。等待相应函数改变model,紧接着触发脏检查机制刷新view。从第一轮到所有数据稳定称为一个完整的digest循环。当循环结束后,才把模型的变化结果更新到dom中去,防止频繁的dom操作。
        <input type="text" ng-model="msg"> 
        <!-- 视图——>模型 -->
    
        <h1 ng-bind="msg"></h1>
        <!-- 模型——>视图 -->
    
        <h1>{{msg}}</h1>
        <!-- 模型——>视图 -->
    

    引入第三方路由模块 ngRoute 配置路由实现单页面开发

    • SPA(Single Page Application)指的是通过单一页面展示所有功能,通过Ajax动态获取数据然后进行实时渲染,结合CSS3动画模仿原生App交互。
        //配置路由
        var Yike = angular.module('Yike',['ngRoute','Controllers']);
        Yike.config(['$routeProvider',function($routeProvider){
            $routeProvider.when('/today',{
                //今日一刻
                templateUrl:'./views/today.html',
                controller:'TodayCtrl'
            }).when('/settings',{
                //设置
                templateUrl:'./views/settings.html',
                controller:'SettingsCtrl'
            }).otherwise({
                redirectTo:'/today'
            });
        }]);
    

    理解MVC、MVVM开发模式

    • MVC(Model View Controller,模型(数据保存)视图控制器):一种软件架构设计模式,它将表现从用户交互中分离出来。通常来讲,模型中包含应用的数据和与数据进行交互的方法,视图将数据呈献给用户,而控制器则是二者之间的桥梁。
      • View 传送指令到 Controller
      • Controller 完成业务逻辑后,要求 Model 改变状态
      • Model 将新的数据发送到 View,用户得到反馈
    • MVP(Model-View-Presenter):把MVC中的Controller换成了Presenter(呈现),目的就是为了完全切断View跟Model之间的联系,由Presenter充当桥梁,做到View-Model之间通信的完全隔离。各部分之间的通信,都是双向的。
    • MVVM(Model-View-ViewModel):将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。唯一的区别是,它采用双向绑定(data-binding):View和Model之间没有联系,通过ViewModel进行交互,而且Model和ViewModel之间的交互是双向的,因此视图的数据的变化会同时修改数据源,而数据源数据的变化也会立即反应到View上。如js框架Knockout、AngularJS等。

    使用directive自定义指令、验证表单字段

        app.directive('tag',function(){
            return {
                //指令调用方式:E:element,C:class,M:mark,A:attribute
                restrict:"ECMA",
                //为true时M显示,不写或为false不显示。是否替换原始标签
                replace:true,
                //指令内容
                template:'<h1>你好 angular</h1>',
                //加载外部文件,需通过服务器访问
                //templateUrl:'./header.html'
            }
        });
    
        <form name="myForm">
            <div class="form-group">
                <label for="">User name:</label>
                <input type="text" class="form-control" name="userName" ensure-unique="username" ng-model="user.name" required>
                <span class="error" ng-show="myForm.userName.$error.unique">Required!</span>
            </div>
            <div class="form-group">
                <label for="">Last name:</label>
                <input type="text" class="form-control" name="lastName" ng-model="user.last" ng-minlength="3" ng-maxlength="10">
                <span class="error" ng-show="myForm.lastName.$error.minlength">Too short!</span>
                <span class="error" ng-show="myForm.lastName.$error.maxlength">Too long!</span>
            </div>
            <div class="form-group">
                <label for="">User age:</label>
                <input type="text" class="form-control" name="userAge" ng-model="user.age" even required>
                <span class="error" ng-show="myForm.userAge.$error.even">数字必须是偶数</span>
            </div>
        </form>
    
        angular.module('MyApp', [])
        .controller('ExampleController', ['$scope', function ($scope) {}])
        .directive('even',function(){
            return {
                restrict:"A",
                require:"ngModel",
                link:function(scope,ele,attrs,ngModelController){
                    //$parsers的值是一个由函数组成的数组,其中的函数会以流水线的形式被逐一调用。ngModel从DOM中读取的值会被传入$parsers中的函数,并依次被其中的解析器处理。
                    ngModelController.$parsers.push(function(viewValue){
                        if(viewValue % 2 === 0){
                            //通过$setValidity()函数设置表单的合法性
                            ngModelController.$setValidity('even',true);
                        }else{
                            ngModelController.$setValidity('even',false);
                        }
                        return viewValue;
                    });
                }
            }
        })
        .directive('ensureUnique', ['$http','$timeout','$window',function($http,$timeout,$window) {
            return {
                restrict:"A",
                require: 'ngModel',
                link: function(scope, ele, attrs, ngModelController) {
                    scope.$watch(attrs.ngModel, function(n) {
                        if (!n) return;
                        $timeout.cancel($window.timer);
                        $window.timer = $timeout(function(){
                            $http({
                                method: 'get',
                                url: '/api/checkusername/', //根据换成自己的url
                                params:{
                                    "username":n
                                }
                            }).success(function(data) {
                                //这个取决于你返回的,其实就是返回一个是否正确的字段,具体的这块可以自己修改根据自己的项目
                                ngModelController.$setValidity('unique', data.isUnique);
                            }).error(function(data) {
                                ngModelController.$setValidity('unique', false);
                            });
                        },500);
                    });
                }
            };
        }]);
    

    自定义指令参数

    • restrict:EACM,默认A
    • terminal:true或false,告诉AngularJS停止运行当前元素上比本指令优先级低的指令。但同当前指令优先级相同的指令还是会被执行
    • template:一段HTML文本或一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个代表模板的字符串
    • templateUrl
    • replace:true或不写。默认值意味着模板会被当作子元素插入到调用此指令的元素内部
    • scope:
      • false:直接调用相同的作用域对象
      • true:从当前作用域对象继承一个新的作用域对象
      • {}:创建一个同当前作用域相隔离的作用域对象

    广播

    使用$httpProvider对请求进行拦截实现权限管理

    • http服务的基础中间件,用来向应用的业务流程中注入新的逻辑。拦截器的核心是服务工厂,通过向httpProvider.interceptors数组中添加服务工厂,在$httpProvider中进行注册。
        //创建拦截器,可以在服务中添加一种或多种拦截器
        angular.module('myApp', []).factory('myInterceptor', function($q) {
            var interceptor = {
                //请求拦截器进行调用。它可以对设置对象进行修改
                'request': function(config) {
                    // 成功的请求方法
                    return config; // 或者 $q.when(config);
                },
                //对响应拦截器进行调用。它可以对响应进行修改
                'response': function(response) {
                    // 响应成功
                    return response; // 或者 $q.when(config);
                },
                //在上一个请求拦截器抛出错误时调用此拦截器
                'requestError': function(rejection) {
                    // 请求发生了错误,如果能从错误中恢复,可以返回一个新的请求或promise
                    return rejection; // 或新的promise
                    // 或者,可以通过返回一个rejection来阻止下一步
                    // return $q.reject(rejection);
                },
                //在上一个响应拦截器抛出错误时调用此拦截器
                'responseError': function(rejection) {
                    // 请求发生了错误,如果能从错误中恢复,可以返回一个新的响应或promise
                    return rejection; // 或新的promise
                    // 或者,可以通过返回一个rejection来阻止下一步
                    // return $q.reject(rejection);
                }
            };
            return interceptor;
        });
        //将实现的拦截器加入到$httpProvider.interceptors数组中,一般在config方法中进行
        myApp.config(['$httpProvider',function($httpProvider) {
            $httpProvider.interceptors.push(myInterceptor);
        }]);
    

    使用angular-translate实现国际化

    • i18n(Internationalization):国际化,在不改变源码的情况下,通过某些简单的配置就能适应不同的语言环境。
    • l10n(Localization):本地化,针对某一些语言进行定制化。
    • angular-translate是一款应用简单、上手容易的国际化服务。它提供了很多的特性:
      • 以组件化的方式形成国际化
      • 异步加载国际化数据
      • 使用messageFormat支持多元化
      • 使用接口提高可扩展性
    • translate中指令是通过过滤器实现的,过滤器是通过服务实现的。
    • 如果使用了requireJS这种异步加载服务,那么需要声明angular-translate与angular的依赖关系
    • 本地化
        shim: {
            angular_translate:{
              deps: ['angular'],
              exports: 'angular_translate'
            }
        }
    
        <div>
            <h1>{{ 'TITLE' | translate }}</h1>  //以过滤器的方式使用
            <span translate="FOO"></span>  //指令的方式使用
        </div>
    
        var app = angular.module("MyApp",['pascalprecht.translate']);
        app.config(['$translateProvider',function($translateProvider){
            //添加翻译表格
            $translateProvider.translations('en',{
                'TITLE':'Hello',
                'FOO':'This is a paragraph'
            });
            $translateProvider.translations('zh',{
                'TITLE':'你好',
                'FOO':'这是一幅图'
            });
            //设置首选语言
            $translateProvider.preferredLanguage('zh');
        }]);
    
    • 运行时切换语言
        app.controller('TranslateController', ['$translate','$scope',function($translate, $scope) {
            $scope.changeLanguage = function(langKey) {
                $translate.use(langKey);
            }
        }]);
    
        <div ng-controller="TranslateController">
            <button ng-click="changeLanguage('de')" translate="TITLE"></button>
            <button ng-click="changeLanguage('en')" translate="FOO"></button>
        </div>
    

    相关文章

      网友评论

          本文标题:AngularJS

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