angularJS知识

 1.介绍
     angular 是Google公司提供的一套开源的javascriptMVC框架。核心功能就是对现有的HTML编码以指令方式进行扩展,并且使扩展后的HTML编码
     可以通过使用元素声明的方式来构建动态内容。-- 通过HTML标签构建动态的web应用。
     
 2.核心
     要实现HTML标签构建动态的Web应用:数据的双向绑定(表达式{{data}})和依赖注入
  
 3.开始
   (1).ng-app
         表示此节点一下为angular的应用
   (2)表达式 {{}}
            表达式是运用在视图中的一段代码 ,表达式的值 通过 $parse 服务模块进行解析的。
        *angular表达式跟js表达式区别
          a.angular表示的值来源于$scope对象 js来自window
          b.angular表达式 的容错率很强 看允许出现null 和undefined 不会像js抛出异常代码
          c.angular不能出现各类判断和循环语句
          d.angular可以出现 "|"管道符进行格式化
        *与js相互转换
          ==>js  $eval()
          ==>angular 采用函数 表达式为函数调用
          
     (3)$window 通过依赖注入
        eg: $window.alert('window 对象')
          
     (4)模板
          构建 js文件的html
             eg: template.js  根据视图的一样
          使用 : 引入  <script src='template.js' type='text/ng-template' id='template'></script>
                html
                  <div ng-inculde src='"template"'></div>
        
     (5)ng-repeat
        track by $index  是每一项都是唯一 如若不加上 当数据相同的时候只会展示一条
            ·$index  记录的索引
            ·$first 记录的第一条
            ·$last    记录的最后一条
            ·$middle 记录的中间条
        
     (6)添加样式
         (1)class类
             a.通过$scope设置变量
                   $scope.addClass = 'container';
                   <div ng-class='{{addClass}}'></div>
                   
             b.字符串数组方式选择性添加css类别名称
                 eg: $scope.isTrue = true;
                     <div ng-class='{true:"test1",false:'test2'}[isTrue]'></div>
                     
             c.通过key/value对象方式
                 eg:  $scope.a = true;
                      $scope.b = false;
                      <div ng-class='{"test1":a,"test2":b}'></div>
                      
             d.通过函数返回字符串
                 eg: 
                     $scope.getClass = function(){
                         return 'test3';
                     }    
                     <div ng-class='getClass'></div>
                     
             ng-class-odd ng-class-even
                    奇偶项
                    eg:
                        css 
                            .odd{color:#333}  .even{color:#666}
                        <div ng-class-odd='"odd"' ng-class-even='"even"'></div>
                        
                     
        (7)显示/隐藏
            ng-show  ng-hide  ng-switch
            显示: ng-show 为true  ng-hide 为false
            eg: $scope.isShow = true
                 $scope.ishide = false
                 <span ng-show='isShow'></span>                       
                 <span ng-show='ishide'></span>                       
            ng-switch  要配合 ng-switch-when 和 ng-switch-default
                    eg:
                        $scope.switch = 2;
                        <ul ng-switch on={{switch}}>
                            <li ng-switch-when='1'></li>
                            <li ng-switch-when='2'></li>
                            <li ng-switch-when='3'></li>
                            <li ng-switch-default>默认</li>
                        </ul>
        
        (8)表单基本验证功能
                $pristine      表示表单或者控件内容是否未输入过    返回布尔
                $dirty        表示表单或者控件内容是否已输入过
                $valid        表示表单或者控件内容是否已验证通过
                $invalid     表示表单或者控件内容是否未验证通过
                $error         表示表单或者控件验证时的错误信息
                
                eg:
                    <form name='myForm' ng-submit='save()'>
                        <div>
                            <input name='myInp' ng-model='email' type='email' requied/>
                            <span ng-show='myForm.myInp.$error.required'>邮件不能为空</span>
                            <span ng-show='myForm.myInp.$error.email'>邮件格式不正确</span>
                        </div>
                        <div>
                            <input type='submit' ng-disabled='myForm.$invalid' value='提交'/>
                        </div>

        (9).select
            a.简单数组
                $scope.arr = ['A','b','C'];
                // ..for...in..
                <select ng-model='seleData' ng-options='item for item in arr'>
                    <option value=''>-- 请选择 --<option>
                </select>
            b.数组对象
                $scope.arrData = [
                    {id:1,name:'张三',age:20},
                    {id:2,name:'李四',age:30},
                    {id:3,name:'王五',age:40}
                ]
                //   ... as...for ...in..
                <select ng-model='seleData' ng-options='item.id as item.name for item in arrData'>
                    <option value=''>-- 请选择 --</option>
                </select>

            c.分组形式
                $scope.arrData = [
                    {id:1,name:'张三',address:'北京'},
                    {id:2,name:'李四',address:'北京'},
                    {id:3,name:'王五',address:'上海'},
                    {id:3,name:'刘二',address:'上海'}
                ]
                //  ... as ... group ... by ... for ... in..
                <select ng-model='seleData' ng-options='item.id as item.name group by item.address for item in arrData'>
                    <option value=''>-- 请选择 --</option>
                </select>
                

        (10)依赖注入
            前言: new object  新创建的对象 依赖于new 后面的原对象 ,这种方式称为创建性依赖。
            而 angualr采用的是注入依赖  angualr通过injector注入器将所依赖的对象进行“注入”操作
            eg:
              var app = angular.module('myApp',[]);
              app.config(function($controllerProvide){
                  $controllerProvide.register('myCtr',['$scope',function($scope){
                      // code by controller
                  }])
              })
             
              上面对控制器的创建 等价于 
               app.controller('myCtr',['$scope',function($scope){
                       // code ny controller
               }])    
               
            原理:  通过模块中的config函数来声明需要注入的依赖对象,而声明的方式是通过调用controllerProvide服务的register方法完成创建
                   当控制器完成后,则再调用inject注入器完成各依赖对象的注入
                   
                   
            config除了controllerProvide 还有 provide服务
               通过provide的provide、factory、service、value方法创建自定义的依赖注入对象
               eg:
                    var app = angular.module('myApp',[]);
                    app.config(function($provide){
                        $provide.provide('proTest',function(){
                            this.$get = function(){
                                return {
                                    val: function(data){
                                        return data;
                                    }
                                }
                            }
                        });
                    });
                    
                    app.config(function($provide){
                        $provide.factory('facTest',function(){
                            return {
                                val: function(data){
                                    return data;
                                }
                            }
                        });
                    });
                    
                    app.config(function($provide){
                        $provide.service('serTest',function(){
                            return {
                                val: function(data){
                                    return data;
                                }
                            }
                        });
                    });
                    
                    app.config(function($provide){
                        $provide.value('valTest',function(data){
                            return data;
                        });
                    });
                    
                   使用:
                   app.controller('myCtr',['$scope','proTest','facTest','serTest','valTest',function($scope,
                   proTest,facTest,serTest,valTest){
                       $scope.pro = proTest.val('111');
                       $scope.fac = facTest.val('111');
                       $scope.ser = serTest.val('111');
                       $scope.val = valTest('111');
                   }]);
                    
                除了在控制器中经常使用依赖注入外 使用工厂方法构建服务时 同样也经常需要注入其他的服务。
                所谓的工厂方法指的是类似于“config” “factory” “directive” “filter” 等构造性的方法 
                eg:
                  angular.module('myApp',[])
                  .factory('facTest',['dep1','dep2',...,function(dep1,dep2,...){
                          // code 
                  }])
            
            依赖注入的方式
                推断式注入   标记式注入  行内式注入
                
            $injector 常用API
                has (是否含有依赖)  get(得到依赖实例)  invoke()执行一个自定义的函数


        (11)服务.
            内置服务  常用的服务  $scope $http $window $location等
               直接在控制器中调用
               
            自定义服务
                一种是使用内置 $provide的内置服务
                eg:
                   angular.module('myApp',[],function($provide){
                           $provide.factory('mySer',function(){
                               return {
                                   val: function(data){
                                       return data;
                                   }
                               }
                           })
                   }).controller('myCtr',['$scope','mySer',function($scop,mySer){
                        $scope.data = mySer.val('hello world!');                   
                   }]);
                   
                另一种是调用模块(modul)中的服务注册方法 factory service consent value等
                factory:
                  app.factory(name,fn)     // app 为构建的模块变量  name 为创建服务的名称 fn为服务的功能函数 可返回一个能被注入对象的数组或函数
                    eg:
                        angular.module('myApp',[])
                        .factory('myFac',function(){
                            return {
                                val: function(data){
                                    return data;
                                }
                            }
                        })  
                  
                service:
                    app.service(name,fn)   // app 为构建的模块变量 name 为创建服务的名称 fn为构造函数 当被注入的时候可以通过new实例化对象
                        eg:
                            angular.module('myApp',[])
                            .service('mySer',function(){
                                this.fn = function(path){
                                    return path;
                                }
                            }).controller('myCtr',function($scope,mySer){
                                $scope.path = mySer.fn('www.baidu.com');
                            });
                            
                consent 和value
                    app.consent(name,value)   返回一个常量
                    app.value(name,value)     返回一个常量
                    
                    eg:
                        angular.module('myApp',[])
                        .consent('myCon',{
                            name:'张三',
                            address:'北京'
                        })
                        .controller('myCtr',function($scope,myCon){
                            $scope.userName = myCon.name;
                            $scope.userAddr = myCon.address;
                        });
                        
                        angular.module('myApp',[])
                        .value('color','#E4393C').controller('myCtr',function($scope,color){
                            $scope.color = color;
                        });
                        
                添加自定义服务的依赖方法
                    1.隐式指明
                        app.factory('myFac',function(dep1,dep2){...})
                        
                    2.调用$inject
                        var fn = function(dep1,dep2){...}
                        fn.$inject = ['dep1','dep2']
                        app.factory('myFac',fn)
                        
                    3.显示声明
                        app.factory('mySer',['dep1','dep2',function(dep1,dep2){...}])
                        
                    
                服务器的装饰器 decorator
                    $provide.decorator('serviceName',fn)
                    eg:
                        angular.module('myApp',[])
                        .factory('myFac',function(){
                            return {
                                name:    '张三',
                                address:'北京'
                            }
                        }).config(function($provide){
                            $provide.decorator('myFac',function($delegate){
                                $delegate.name = '李四';
                                return $delegate;
                            })
                        }).controller('myCtr',function($scope,myFac){
                            $scope.user = myfac;
                            console.log($scope.user.name); // 李四
                        });
                    
                        
        (12)与服务端交互
            1.使用$http快捷方法
                $http.method(url,[data],[config])
                .success(data,status,headers,config)
                .error(data,status,header,config)
                
            eg:
                angular.module('myApp',[])
                .config(function($httpProvide){
                    $httpProvide.defaults.headers.post = {
                        'content-Type':'application/x-www-form-urlencoded'
                    }
                }).controller('myCtr',function($scope,$http){
                    var params     = {name:'张三',address:'北京'};
                    var url     = 'wewewe.com/sdsds/dsd';
                    $http.post(url,params)
                    .success(function(data){
                        console.log(data);
                    })
                    .error(function(error){
                        console.log(error)
                    })
                })        
                
            2.使用$http配置对象方式与服务端交互
                $http({
                    method:'POST',
                    url:'....',
                    data:data,
                    params:
                    transformRequest:
                    transformResponse:
                    cache:
                    timeout:
                }).success(fn1).error(fn2)
                
                等价于
                $http({
                    //配置对象
                }).then(fn1,fn2)
                       
                
        (13)缓存
            angular 提供 $cacheFactory 服务缓存 
            
            格式:
                $cacheFactory(key,[options])      // key 表示缓存对象的名称  options是一个对象用于指定缓存的特征
                $cacheFactory.get(key)              // 创建或获取缓存对象
                
            1.info 方法
                var cache = $cacheFactory("test");
                console.log(cache.info())    // 缓存对象的大小和名称信息
                
            2.put 方法
                put方法可以向缓存对象中以key/value的形式添加缓存内容
                    cache.put('test','hello')
                    
            3.get 方法
                get方法可以获取键名对应的键值
                  cache.get('test')
                  
            4.remove 方法
                remove方法用于移除指定键名的缓存
                    cache.remove('test')
                    
            5.removeAll 和 destory方法
                removeAll 移除全部的缓存内容 并且重置缓存结构 
                destory 是从 $cacheFactory 缓存注册表中删除所有的缓存引用条目,并且重置缓存对象
                
            eg:
                angular.module('myApp',[])
                .service('cache',function($cacheFactory){
                    return $cacheFactory('test')
                })        
                
            
    (14)promise 对象
         angular 中创建一个promise对象 必须在模板中先注入$q服务,并先调用defer方法创建一个延期对象
          eg:
              angular.module('myApp',function($scope,$q){
                  var defer = $q.defer();
              })            
            
        defer 是一个延期对象 包括3个方法 分别是 notify resolve reject 和"promise"属性
        当调用延期对象的"promise"的属性时 就创建一个promise对象
        eg:
            var promise = defer.promise
            promise.then(successCallback,errorCallback,notifyCallback)
            
        promise 在$http中的应用
            angular.module('myApp',[])
            .factory('myFac',function($q,$http){
                var defer = $q.defer()
                $http.get(url)
                .success(function(data){
                    defer.resovle(data);
                })
                .error(function(reson){
                    defer.reject(reson)
                })
                return defer.promise
            }).controller('myCtr',function($scope,myFac){
                myFac.then(function(data){
                    console.log(data)
                })
            })
        
    (15)指令   
            一种执行的信号  eg html中a标签 告诉浏览器的编译系统,要创建一个超链接 angular指令是一个在特定DOM元素上执行的函数
        指令是angular的一个特殊标志 也是有别于其他框架的一个重要特征 angular之所以功能强大,在很大
        的程度上得益于它拥有大量内置的指令 也能通过语法自定义指令。可以说指令是开发angular应用时一个
        非常重要的道具,尤其是自定义的指令
        自定义指令:调用directive方法
            语法:
                app.directive(name,fn)
                
            eg:
                app.directive('myDire',function(){
                    return {
                        restrict: 'EA',
                        template: '<h1>hello world</h1>',
                        replace:true
                    }
                })
                <my-dire></my-dire>    或者  <div my-dire></div>
                
            说明:
                restrict  指出在HTML中的使用方式  包括: E (元素) A(属性) C(类) M(注释) 可以是一种或者组合
                template  模板    templateUrl 模板文件
                replace  是否替换指令标记
                
            几个重要的属性
                transclude    <Boolean>  一旦开启属性 可以将调用指令后的元素替换为指令中的模板内容,如果模板中的内容没有元素标签,
                                        而是纯文本内容,那么在替换时会自动添加一个<sapn>标签 不仅仅是内容的替换
                                        
                eg:
                    angular.module('myApp',[])
                    .directive('myDir',function(){
                        return {
                            restrict:'EA',
                            template: '<div>'+
                                            '<input type="text" ng-model="text" />'+
                                            '<div ng-translude></div>'+
                                        '</div>',
                            transclude: true
                        }
                    })
                    
                    <my-dir>{{text}}</my-dir>
                
                link 属性
                    link属性值是一个函数 在该函数中科院操控DOM元素对象 包括绑定的各类事件 定义事件触发执行的内容
                    link: function(scope,iEle,iAttrs){
                        // code
                    }
                     scope: 表示指令所在的作用域 其功能跟控制器中注入的作用域是相同的
                     iELe: 指令中的元素  该元素可以通过angular内部封装的jqLite框架进行调用  jqLite框架与jquery框架
                             在功能上差别很大 但是它包含了主要元素操作的api 是一个压缩版的jquery 在语法上与jquery相同
                     iAttrs: 指令元素的属性集合 通过这个参数可以获取元素中的各类属性
                     
                    eg:
                        angular.module('app',[])
                            .directive('myDir',function(){
                                return {
                                    restrict:'EA',
                                    template: '<div><button>点击</button><span>{{text}}</span></div>',
                                    transclude: true,
                                    link: function (scope,iEle,iAttrs) {
                                        iEle.bind('click',function(){
                                            scope.$apply(function () {
                                                scope.text = '点击以后'
                                            })
                    
                                        })
                                    }
                                }
                            })
                            
                        <div ng-app="app">
                                <my-dir></my-dir>
                            <div>{{text}}</div>
                        </div>
            
            complete 属性
                返回一个函数或者一个对象  一个函数 函数名为post  返回对象 包含两个 pre post名的方法函数 系统提供不可更改
                注: 当添加complete时  不能再添加link属性
                eg:
                    app.directive('dir',function(){
                        return {
                            restrict:'EA',
                            compile: function(tEle,tAttrs,trans){
                                return {
                                    pre: function(scope,iEle,iAttrs){
                                        // code
                                    },
                                    post: function(scope,iEle,iAttrs){
                                        // code
                                    }
                                }
                            }
                        }
                    })
                
            scope 属性
                属性值 Boolean 为true 创建新的作用域 父、子作用域数据完全不相同
                                false 不创建新的作用域  父、子作用域数据完全相同
                                
                属性值为JSON时
                    JSON对象添加的3中策略  "@attrName"  "=attrName"  "&attrName"
                    '='  父变子也变   字变父也变    一般为值     值用{{}}
                    '@'  父变字变      字变父不变   一般为值       值用 ''
                    '&'  一般为函数                                           用      '()'
                    
                
                
            eg:
                <div ng-app="app" ng-controller="myCtr">
                    <div>
                        <input type="text" ng-model="username" placeholder="名字">
                    </div>
                    <div>
                        <input type="text" ng-model="userphone" placeholder="电话号码">
                    </div>
                    <my-dir uname="username" uphone="{{userphone}}" uage="userage()"></my-dir>
                </div>    
                <script>
                    angular.module('app',[])
                        .controller('myCtr',function($scope){
                            $scope.userage = function(){
                                $scope.username = '张三';
                                $scope.userphone = '1111111111111';
                            }
                        })
                        .directive('myDir',function(){
                            return {
                                scope:{
                                    usname:'=uname',
                                    usphone:'@uphone',
                                    usage:'&uage'
                                },
                                restrict:'EA',
                                template: '<div>' +
                                '<input type="text" ng-model="usname" placeholder="姓名">' +
                                '<input type="text" ng-model="usphone" placeholder="电话号码">' +
                                '<button>修改</button>' +
                                '</div>',
                                transclude: true,
                                link: function (scope,iEle,iAttrs) {
                                    scope.usname = '李四';
                                    scope.usphone = '22222';
                                    iEle.bind('click',function(){
                                        scope.$apply(function () {
                                            scope.usage();
                                        })
                
                                    })
                                }
                            }
                        })
                    </script>
            

            require 和 controller属性  用于多级指令 或者指令嵌套


        (16) $location
            提供只读和读写api
            只读
                absUrl: URL地址中编码后的完整内容 
                protocol: 协议
                host: 主机名称
                port: 端口号
            
            eg:
                angular.module('myApp',[])
                .controller('myCtr',['$scope','$location',function($scope,$location){
                    $scope.absUrl     = $location.absUrl();
                    $scope.protocol = $location.protocol();
                    $scope.host     = $location.host();
                    $scope.port     = $location.port();
                }])

            读写方法:加参数表示重置  不加参数表示获取  返回$location对象 所以支持链式调用
                url:      修改/获取"#"后面的内容
                hash:      修改/修改hash
                search:修改/查询 查询字符串内容
                path:    修改/查询当前路径

            事件:
                $locationChangeStart   url地址发生改变之前
                eg:
                    angular.module('myApp',[])
                    .controller('myCtr',function($scope,$rootScope,$location){
                        $rootScope.$on('$locationChangeStart',function(evt,current,previous){
                            
                        })
                    })
                
                其中 
                    evt: 表示触发是时的原始事件对象
                    current: 当前的url地址
                    previous: 表示上一级的url地址  如果首次加载 为undefined
                    
                    
                $locationChangeSuccess    URl地址完成改变后触发
                  参数与$locationChangeStart 一直
                  
            路由模式和地址变更
                路由模式分为标签(hashbang)和HTML5两种模式
                hashbang :angular默认的路由模式 是HTML5模式的降级方案  url会 "#"符号开头 后面紧跟着
                            一个"!"符号
                    重置:
                        $locationProvide.html5Mode('boolean || obj')
                        
                        true : 表示支持html5模式 反之支持标签模式
                        obj :  {enabled:true} 支持html5模式  {enabled:false} 支持标签模式 

                区别:
                                            标签模式                    html5模式
                    是否默认                    是
                    显示格式            所有浏览器显示标签url格式            支持HTML5history API 显示 其他为标签格式
                    连接标签是否重写                 否                            是
                    是否需要服务端支持        否                            是

        (17)angular 开发的注意事项和最佳实践
            1.建议不再调用jQuery框架 避免两者之间在调用时发生冲突  angualr内含jQlite (jquery的一个子集)
                操作DOM可以使用自定义指令
                
            2.dom操作
                angular.element(element)
                    形参element是字符型 (字符串或者DOM元素)  功能是调用 angular内部的jQLite库 返回jQuery对象
                    
                eg:
                    <div ng-app="app" ng-controller="myCtr">
                        <div><button ng-click="add()">添加</button></div>
                        <div><button ng-click="del()">删除</button></div>
                        <ul id="doms">
                            <li>第一</li>
                            <li>第二</li>
                            <li>第三</li>
                        </ul>
                    </div>
                    
                    <script>
                        angular.module('app',[])
                            .controller('myCtr',function($scope,$compile){
                                var htmlTem = '<li>第四</li>';
                                var template = angular.element(htmlTem);
                                var newTemplte = $compile(template)($scope);
                                $scope.add = function(){
                                    angular.element(document.getElementById('doms')).append(newTemplte);
                                };
                                $scope.del = function(){
                                  if(newTemplte){
                                      newTemplte.remove()
                                  }
                                };
                            })
                    </script>
            
                $compile 服务时把dom转为Jquery对象 进行编译 一遍调用append方法

            3.setTimeout改变属性无效
                在angular中调用其他方法  并不会执行 自动执行 $apple  只有绑定在$scope上才会 或者 内置的服务
                基于以上两种解决办法
                    1.
                        setTimeout(function(){
                            $scope.$apply(function(){
                                // code
                            })
                        },1000)
                        
                    2.
                        $timeout(function(){
                            // code
                        },1000)    
                        
            4.解决双大括号 {{}}绑定元素时闪烁问题
                原因: dom加载完成 而数据为渲染完
                解决:
                    可以向元素添加 ng-cloak 属性实现掩藏的效果  纯文本 可以使用 ng-bind='data'  避免使用 {{}}
                    
                eg:
                    <p ng-cloak>{{message}}</p> 
                        ng-cloak 实质会在页面 head添加css样式 让dom 的display 为none 当数据渲染成功以后移除样式
                
                    
                    <p ng-bind='message'></p>


            5.ng-repeat 问题
                a.如果使用了过滤器不能通过$index 定位到对象
                b.ng-repeat 的更新数据是重建dom而不是更新
                    使用 track by .. 排序解决
                    
                c.与scope关系
                    ng-repeat 新建dom会为每个新建的dom元素创建独立的作用域  但是父级的scope是相同的 通过调用 
                    angular.element(domELement).scope() 可以获取某个DOM元素所在的作用域

            6.单击事件冒泡
                阻止冒泡
                    <button ng-click='fn($event)'></button>
                    app.controller('myCtr',function($scope){
                        $scope.fn = function(event){
                            event.stopPropagation();
                        }
                    })

            7.释放多余的 $watch监听 函数
                $scope.$watch() 返回$watch 绑定的unbind函数   再次调用 就可以释放它的监听功能
                eg:
                    var watchFun = $scope.$watch('value',function(newValue,oldValue){
                        // code
                    });
                    
                    warchFun();  // 停止监听


            8.ng-if 中ng-model值无效 的问题
                ng-if指令的功能 与ng-show指令相似 可以控制元素的显示和隐藏
                区别: ng-if 指令会移除DOM原有的元素 而 ng-show 指令 只是将元素的 "display" 属性设置"none"
                    ng-if 会生成一个子作用域 从而与 ng-model无效绑定
                解决:
                    1. 替换 ng-show
                    2.添加标识 $parent
                        eg:
                            <div>{{msg}}</div>
                            
                            <div ng-if='isShow'>
                                <input type='text' ng-model='$parent.msg'/>    
                            </div>
                            
                    
                
                

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值