• angularjs 知识点


    1. $eval 方法对绑定的属性值直接进行解析

    <input type='text' ng-model = 'expr2/>
    <span ng-bing='$eval(expr2)'></span>
    
    
    
    $scope.expr2 = '20 + 1 | number:0';

    2. ng-repeat

    指令复制元素-在复制过程中可以添加元素相应的属性-专有变量

    $first

    $last

    $middle

    $index

    <span>{{$first?'yes':'no"}}</span

    3. 添加元素样式

    $scope.red = "red";
    <div ng-class="{{red}}"></div>
    <div class="{{red}}"></div>

    字符串数组形式添加样式

    $scope.blnfocus = false;
    <div ng-class="{true:'red',false:'green'}[blnfocus]"></div>

    定义key/value对象的方式添加多个css样式

    $scope.a = false;
    $scope.b = true;
    <div ng-class="{'red':a,'green':b}"></div>

    4. 控制元素显示,隐藏状态

    页面中调用ng-show,ng-hide,ng-switch指令绑定$scope对象的属性值

    ng-switch 指令中 on可有可无,当on于多个或某个ng-switch-when指令的元素匹配时,这些元素显示,如果没有匹配的ng-switch-default显示.

    <div ng-show = {{isShow}}> div </div>
    <div ng-hide = {{isHide}}>hide</div>
    <ul ng-switch on={{switch}}>
        <li ng-switch-when="1">taoguorong</li>
        <li ng-switch -default>more</li>
    </ul>

    5. 表单基本验证功能

    $pristine:表单或控件内容是否未输入过

    $dirty:表单或控件内容是否已输入过

    $valid:表单或控件内容是否已验证通过

    $invalid:表单或空间内容是否未验证通过

    $error:表单或控件验证时的错误提示信息

    <form name="temp_form" ng-submit="save()">
        <div>
            <input name="t_email" ng-model = "email" type="email" required/>
            <span ng-show="temp_form.t_email.$error.required>
                邮件不能为空
           </span>
           <span ng-show="temp_form.t_email.$error.email>
               邮件格式不对
           </span
        </div>
         <input type = "button" ng-disabled="temp_form.$invalid" value="提交"/>
    </form>    

    6. 表单中的checkbox控件和redio控件

    通过ng-model绑定控制器的属性,一旦绑定完成,首次加载时,将以绑定的值作为控件的初始化状态.

    <form name="temp_form" ng-submit="save()">
        <div>
            <input name="t_email" ng-model = "email" type="email" required/>
            <span ng-show="temp_form.t_email.$error.required>
                邮件不能为空
           </span>
           <span ng-show="temp_form.t_email.$error.email>
               邮件格式不对
           </span
        </div>
        <div>
            <input type="checkbox" ng-model = "a"  ng-true-value="同意" ng-false-value = "不同意">同意
        </div>
         <div>
            <input type="rediio" ng-model = "a"  value=""><input type="rediio" ng-model = "a"  value=""></div>
         <input type = "button" ng-disabled="temp_form.$invalid" value="提交"/>
    </form>        

    ng-true-value表示选中后返回的值,后者表示没有被选中时返回的值,redio只有被选中的会返回其被选中的值.

    7. 表单中的select控件

    可以借助ng-option指令属性,将数组,对象类型的数据添加到<option>元素中,同时还能在添加数据时进行分组显示.

    绑定简单的数据类型:

    通过ng-option指令属性值,采用...for...in...格式将数组与<select>控件绑定

    绑定简单的对象数据

    通过ng-option指令属性值,采用...as...for...in...格式将对象与<select>控件绑定,as前面部分对应元素的value值,用于选中时获取,as后面部分对应元素的text值,用于直接显示

    以分组的形式绑定对象数据

    通过ng-option指令属性值,采用...as...group by for..in...

    <body>
            <form name="temp_form" ng-controller = "testController">
                <div>学制:
                    <select ng-model = "a" ng-options = "v.id as v.name for v in a_data" ng-change="a_change(a)">
                        <option value="">--请选择--</option>
                    </select>
                    <span>{{a_show}}</span>
                </div>
                <div>
                    班级:
                    <select ng-model="b" ng-options="v.id as v.name group by v.grade for v in b_data" ng-change="b_change(b)">
                        <option value="">--请选择--</option>
                    </select>
                    <span>{{b_show}}</span>
                </div>
            </form>
            <div>{{8.8  | number:1 | currency}}</div>
            <script type="application/javascript">
            var con = angular.module('main',[]);
            con.controller('testController',['$scope',function($scope){
                $scope.a_data=[
                {id:"1001",name:"小学"},
                {id:"1002",name:"初中"},
                {id:"1003",name:"大学"}
                ];
                $scope.b_data=[
                {id:"1001",name:"(1)班",grade:"一年级"},
                {id:"1002",name:"(2)班",grade:"二年级"},
                {id:"2001",name:"(1)班",grade:"一年级"},
                {id:"2002",name:"(2)班",grade:"二年级"},
                {id:"3001",name:"(1)班",grade:"一年级"},
                {id:"3002",name:"(2)班",grade:"二年级"}
                ];
                $scope.a = "";
                $scope.b = "";
                $scope.a_change = function(a){
                    $scope.a_show = "you selected is " + a;
                    console.info("you selected is " + a);
                }
                $scope.b_change = function(b){
                    $scope.b_show = "you selected is " + b;
                    console.info("you selected is " + b);
                }
            }])
        </script>
        </body>

     8.过滤器

      过滤器的主要功能是格式化数据,这里所说的数据包括视图模板中的表达式,也包括控制器中的数组和对象.

      过滤器的三种调用方式:

      1.单个过滤器

        {{}}双括号为表达式标记,在括号中 | 为管道符,通过该符号分为前后两部分,前部分为表达式,后部分为过滤器名称

      

    <div>{{8.8  | number:1 | currency}}</div>

      number过滤器要放在currency过滤器前边,原因大家懂得

      2.多个过滤器

      {{表达式 | 过滤器1 | 过滤器2 | ...}}

      3.带参数的过滤器

      {{表达式 | 过滤器1 :参数1 : 参数2}}

      currency:货币过滤器
      number:四舍五入小数点个数过滤器

      排序方式过滤:

    $scope.data = [
       {name:"张晓明",sex:"男",age:"24",score:95}
    ]
    <li ng-repeat="stu in data | orderBy:'-score' | limitTo:3" ng-class-odd="'odd'" ng-class-even="'even'"></li>

       匹配方式过滤:

      {{数据 | filter:'匹配字符'}},一旦添加该参数,将在整个数据的属性中查找匹配项,找到后则显示,找不到则不显示,字符内容必须加引号

      {{data | filter:80}},在data数据的各个属性中查找包含"80"内容的记录

      在字符参数中使用对象形式匹配指定属性的数据:

      如果在过滤数据时已经确定了数据匹配的属性范围,可以在字符参数中通过对象的形式指定匹配的属性名称,如下

      {{数据 | filter:对象}}

      上述调用格式的对象中,过滤器参数是一个对象,这个对象通过key/value方式声明属性名称和匹配的字符内容,如果属性名称为$,则表示在全部的属性中查找,如下

      {{data | filter:{score:80}}}    {{data | filter:{$:80}}}

      后者相当于{{data | filter:80}}

      在字符参数中使用自定义函数匹配相应数据:

      {{数据 | filter:函数名称}}

      参数默认传递循环过程中的当前元素

    <div>
                <ul>
                    <li>
                        <span>序号</span>
                        <span>姓名</span>
                        <span>性别</span>
                        <span>年龄</span>
                        <span>分数</span>
                    </li>
                    <li ng-repeat="stu in data | filter:findscore" ng-class-odd="'odd'" ng-class-even="'even'">
                        <span>{{$index + 1}}</span>
                        <span>{{stu.name}}</span>
                        <span>{{stu.sex}}</span>
                        <span>{{stu.age}}</span>
                        <span>{{stu.score}}</span>
                    </li>
                </ul>
            </div>
    var con = angular.module('main',[]);
            con.controller('testController',['$scope',function($scope){
                $scope.a_data=[
                {id:"1001",name:"小学"},
                {id:"1002",name:"初中"},
                {id:"1003",name:"大学"}
                ];
                $scope.b_data=[
                {id:"1001",name:"(1)班",grade:"一年级"},
                {id:"1002",name:"(2)班",grade:"二年级"},
                {id:"2001",name:"(1)班",grade:"一年级"},
                {id:"2002",name:"(2)班",grade:"二年级"},
                {id:"3001",name:"(1)班",grade:"一年级"},
                {id:"3002",name:"(2)班",grade:"二年级"}
                ];
                $scope.data = [
                    {name:"张晓明",sex:"",age:"24",score:95},
                    {name:"李晓东",sex:"",age:"25",score:80},
                    {name:"马晓华",sex:"",age:"30",score:85},
                    {name:"师小婕",sex:"",age:"23",score:100}
                ];
                $scope.findscore = function (e){
                    return e.score >80 && e.score < 100;
                }

      自定义过滤器:

        在页面模块中注册一个过滤器的构造方法,改方法将返回一个以输入值为首个参数的函数,在函数体中实现过滤器功能.而输入值为默认的被传入过滤器的对象.

        

    <ul>
                    <li>
                        <span>序号</span>
                        <span>姓名</span>
                        <span>性别</span>
                        <span>年龄</span>
                        <span>分数</span>
                    </li>
                    <li ng-repeat="stu in data | young:0" ng-class-odd="'odd'" ng-class-even="'even'">
                        <span>{{$index + 1}}</span>
                        <span>{{stu.name}}</span>
                        <span>{{stu.sex}}</span>
                        <span>{{stu.age}}</span>
                        <span>{{stu.score}}</span>
                    </li>
                </ul>
    con.filter('young',function(){
                return function(e,type){
                    var _out = [];
                    var _sex = type ? "" : "";
                    for(var i = 0; i < e.length; i++){
                        if(e[i].age > 22 && e[i].age < 30 && e[i].sex == _sex){
                            _out.push(e[i]);
                        }
                    }
                    return _out;
                }
            })

    过滤器默认传入参数e,代表当前元素.在自定义过滤器中,当前元素代表整个集合对象,在自定义函数过滤器中当前元素为整个结合对象中的当前循环元素.

    返回以输入值(被过滤值)为首个参数的函数,通过return返回一个函数,参数e为在调用过滤器时,会被过滤的数据自动注入的,其他参数为过滤器传入的自定义参数,通过冒号向过滤器传递,先定义返回值,在做逻辑处理.

    表头排序:

    <ul>
                    <li>
                        <span>序号</span>
                        <span  ng-click="title='name';desc = !desc">姓名</span>
                        <span ng-click="title='sex';desc = !desc">性别</span>
                        <span ng-click="title='age';desc = !desc">年龄</span>
                        <span ng-click="title='score';desc = !desc">分数</span>
                    </li>
                    <li ng-repeat="stu in data | orderBy:title:desc" ng-class-odd="'odd'" ng-class-even="'even'">
                        <span>{{$index + 1}}</span>
                        <span>{{stu.name}}</span>
                        <span>{{stu.sex}}</span>
                        <span>{{stu.age}}</span>
                        <span>{{stu.score}}</span>
                    </li>
                </ul>
            </div>
    con.controller('testController',['$scope',function($scope){
                $scope.desc = 0;
                $scope.title = "name";

    确定controller作用域后,controller为变量初始化,这个时候变量已经被赋值,函数变量会被初始化,但是不会执行函数.

    orderBy过滤器带有两个参数,第一个参数指定排序的属性名,第二个参数指定排序的方向,该值默认或缺省时为升序,1为降序,0为升序.

    字符查找:

    <li ng-repeat="stu in data | filter : {name:key}" ng-class-odd="'odd'" ng-class-even="'even'">
    $scope.key = ' ';
    {name:"师小婕 ",sex:"",age:"23",score:100}

    name引号可有可无.

    9.作用域:

    作用域能存储数据模型,为表达式提供上下文环境和监听表达式变化并传播事件,它是页面视图和控制器之间的重要桥梁.

    提供了$watch方法来监听数据模型的变化,ng-model实现双向数据绑定就是通过该方法进行数据模型的监听.

    提供了$apply方法为各种类型的数据模型改变提供支撑,例如通过视图模板中的ng-click来执行控制器中的代码.

    提供了执行环境,一个表达式必须在拥有该表达式属性的作用域中执行,作用域通过提供$scope对象,使所有的表达式对象都拥有执行环境.

    $watch:

    <div>
                <div>
                    <input type="text" ng-model = "name" placeholder="please input you name" />
                </div>
                <div>累计变化次数:{{count}}</div>
            </div>
    $scope.count = 0;
                $scope.name = '';
                $scope.$watch('name',function(){
                    $scope.count ++;
                })

    需要注意的是第一次加载时初始化过程中也是认为该值是改变的undefined--初始化,该方法也会执行.

    作为数据模型的作用域:

    作用域是控制器和视图的桥梁,同时作用域也是指令和视图的桥梁,无论是指令,还是控制器他们都可以通过作用域与视图中的DOM进行绑定.两条数据关系链

    指令->作用域->视图      控制器->作用域->视图

    作用域的层级和事件:

    子级作用域可以继承父级作用域中的全部属性和方法,同级别子作用域不可以相互访问各自的属性和方法.

     引入作用域

    con.controller('testController',['$scope',function($scope){

    作用域事件传播:

    两种方式可以实现作用域间的通信

      服务(service):

      事件(event):

         Angular中提供的两个方法:$broadcasted,$emitted

         $broadcasted:将事件从父级作用域传播到子级作用域

         $broadcasted(eventname,data) data为事件传播过程中携带的数据信息.

           $emitted:将事件从子级作用域传播到父级作用域

         $emitted(eventname,data)

      除了这两个传播事件的方法外,还需要调用$on方法,在作用域中监控传播来的事件,并获取相应的数据.$on(eventname,function(event,data){接收传播事件的处理方法})

      在一个作用域中定义事件的传播,然后在其他作用域中通过$on方法监控事件传播的状态.

    不同controller的作用域不同,通过调用作用域中的函数,并定义事件的传播,在其他的作用域中监听事件传播.
    controller1
                         $scope.to_patient = function(){
                    $scope.$emit('event_1',"事件来源于子级")
                }
                $scope.to_child = function(){
                    $scope.$broadcast('event_2',"事件来源于父级")
                }
    controller2
                $scope.$on('event_1',function(event,data){
                    ...
                })                

    在监听函数中通过event下边相关方法操作被监听的域中的相关操作

    10.依赖注入:

    依赖注入原理:

    var myApp = angular.module('myapp',[]);
                myApp.controller('ctl',['$scope',function($scope){
                    
                }])
    myApp.config(function($controllerProvider){
                    $controllerProvider.register('ctl',['$scope'.Function($scope){
                        
                    }])
                })

    第一段代码为常用代码,第一段代码在Angular中执行的本质其实是第二段代码.

    11.angular中mvc模式:

    模板跳转:

    <a href="#view/{{stu.stuId}}>{{stu.stuName}}</a>
    
    $routeProvider.when('/view/:id',{
    
    controller:'ctl',
    
    templateUrl:'aa.html',
    
    publicAccess:true
    
    })
    
    myApp.controller('ctl',function($scope,$routeParams){
    
    for(var i = 0;i<students.length;i++){
    
      if(students[i].stuId == $routeParams.id){
    
      $scope.student = students[i]; 
    
      }
    
    }
    
    })

    12. Angular 的服务

    在Angular中服务是一种单利对象,服务的主要功能是为实现应用的功能提供数据和对象.按照功能不同,分为内置和自定义的服务.

    内置服务如:$scope,$http,$windows,$location

    $location:

    获取当前地址栏中完整的url地址.

    myApp.controller('ctl1',function($scope,$location){
                    $scope.clicked = function(){
                        $scope.url = $location.absUrl();
                    }
                })

    自定义服务:

    只需将服务注入到需要服务的容器中(控制器,指令,或其他自定义服务)就可以采用对象的方式调用服务中的属性和方法

    定义服务的方法主要包含两种,一种是使用内置的$provider服务,一种是调用模块中的服务注册方法,如factory,service,constant,value等方法

    添加自定义服务依赖选项方法:

    隐式声明:指的是在创建服务的函数中,直接在参数中调用,不进行任何声明,如果对代码进行压缩时,注入的对象可能失效

    app.factory('serviceName',function(dep1,dep2){});

    调用$inject属性:将需要注入服务的各种对象包装成一个数组,并将它们作为$inject属性值,但是执行效率很低,不推荐

    sf表示服务执行的函数

    var sf = functioin(dep1,dep2){};
    sf.$inject = ['dep1','dep2'];
    app.factory('ServiceName',sf);

    显示声明:指的是在创建服务的函数中,添加一个数组,在数组中顺序声明需要注入的服务或对象名称,高效,不丢代码,推荐使用,参数中的名称和声明可以不一样但是顺序必须一样

    app.factory('serviceName',['dep1','dep2',function(dep1,dep2){}]);

    && 通过指令在ng-repeat中动态添加删除class

    <li  ng-repeat="stu in data | filter : {name:key}" ng-class-odd="'odd'" ng-class-even="'even'">
                        <span repeat-my >{{$index + 1}}</span>
                        <span repeat-my>{{stu.name}}</span>
                        <span repeat-my>{{stu.sex}}</span>
                        <span repeat-my>{{stu.age}}</span>
                        <span repeat-my>{{stu.score}}</span>
                    </li>
    con.directive("repeatMy",function(){
                return {
                    restrict:"A",
                    link:function(scope,elem,attrs){
                        elem.bind('click',function(){
                            var test = attrs.$$element[0];
                            console.info(test.getAttribute('class').indexOf('ok'))
                            if(test.getAttribute('class').indexOf('ok') > 0){
                                elem.removeClass("ok");
                            }else{
                                elem.addClass("ok");
                            }
                        })
                    }
                }
            })

     13. $apply Scope提供$apply方法传播Model的变化

     什么时候使用$apply()方法呢?情况非常少,实际上几乎我们所有的代码都包在scope.apply()里面,像ng−click,controller的初始化,http的回调函数等。在这些情况下,我们不需要自己调用,实际上我们也不能自己调用,否则在apply()方法里面再调用apply()方法会抛出错误。如果我们需要在一个新的执行序列中运行代码时才真正需要用到它,而且当且仅当这个新的执行序列不是被angular JS的库的方法创建的,这个时候我们需要将代码用scope.apply()包起来。下面用一个例子解释:
    
    <div ng:app ng-controller="Ctrl">{{message}}</div>
    
    functionCtrl($scope) {
      $scope.message ="Waiting 2000ms for update";   
      setTimeout(function () {
        $scope.message ="Timeout called!";
         // AngularJS unaware of update to $scope
      }, 2000);
    }
    
         上面的代码执行后页面上会显示:Waiting 2000ms for update。显然数据的更新没有被angular JS觉察到。
         接下来,我们将Javascript的代码稍作修改,用scope.apply()包起来。
    
    
    functionCtrl($scope) {
      $scope.message ="Waiting 2000ms for update";
      setTimeout(function () {
        $scope.$apply(function () {
           $scope.message ="Timeout called!";
          });
      }, 2000);
    }
    
         这次与之前不同的是,页面上先会显示:Waiting 2000ms for update,等待2秒后内容会被更改为:Timeout called! 。显然数据的更新被angular JS觉察到了。
         NOTE:我们不应该这样做,而是用angular JS提供的timeout方法,这样它就会被自动用apply方法包起来了。
    
    科学是把双刃剑
         最后,我们再来瞅一眼scope.apply()和scope.apply(function)方法吧!虽然angular JS为我们做了很多事情,但是我们也因此丢失了一些机会。从下面的伪代码一看便知:
    
    function$apply(expr) {
      try {
        return$eval(expr);
      } catch(e) {
        $exceptionHandler(e);
      } finally {
        $root.$digest();
      }
    }
    
      它会捕获所有的异常并且不会再抛出来,最后都会调用$digest()方法。
    
    总结一下
    
      $apply()方法可以在angular框架之外执行angular JS的表达式,例如:DOM事件、setTimeout、XHR或其他第三方的库。这仅仅是个开始,水还有很深,欢迎大家一起来deep dive!

     14.scope.$watch

    $watch(watchFn,watchAction,deepWatch)

    watchFn:angular表达式或函数的字符串

    watchAction(newValue,oldValue,scope):watchFn发生变化会被调用

    deepWatch:可选的布尔值命令检查被监控的对象的每个属性是否发生变化

    $watch会返回一个函数,想要注销这个watch可以使用函数

    scope.$watch(
            function () {
              return scope.$eval(attrs.bfAssertSameAs);
            },
            function () {
              ngModel.$setValidity('same', isSame(ngModel.$modelValue));
            }
          );
    var firstController = function ($scope){
        $scope.name='张三';
         
        $scope.count=0;
         
        // 监听一个model 当一个model每次改变时 都会触发第2个函数
        $scope.$watch('name',function(newValue,oldValue){
     
            ++$scope.count;
     
            if($scope.count > 30){
                $scope.name = '已经大于30次了';
            }
        });
     
    }

     15.通过指令获取元素的值,以及作用域中的其他值

    16.页面追加元素

    angular.module("com.ngnice.app").directive('bfFieldError', function bfFieldError($compile){
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function(scope, element, attrs, ngModel){
                var subScope = scope.$new(true);
                subScope.hasError = function(){
                    return ngModel.$invalid && ngModel.$dirty;
                };
                subScope.errors = function(){
                    return ngModel.$error;
                };
                var hint = $compile('<ul class="" ng-if="hasError()"><li ng-repeat="(name,wrong) in errors()" ng-if="wrong">{{name | error}}</li></ul>')(subScope);
                element.after(hint);
            }
        };
    });

     17. 删除数组元素

    $scope.array.splice($.inArray(id, $scope.array), 1);
    

     18. 按钮变换,焦点获取

    <tbody>
                    <tr ng-repeat="cor in cors">
    
                        <td>{{$index + 1}}</td>
                        <td>{{cor.mistake}}</td>
                        <td style="padding: 0px 0px;">
                            <input type="text" name="correction" class="form-control" ng-model="cor.correction" readonly/>
                        </td>
                        <td>{{cor.operator}}</td>
                        <td>{{cor.updatetime | date:'yyyy-MM-dd hh:mm:ss'}}</td>
                        <td>
                            <a href="javascript:void(0)" class="operate_a" ng-click="editSec($event,cor.id,cor.correction)">编辑</a>
                            <a href="javascript:void(0)" class="operate_a" ng-click="deleteCor(cor.id)">删除</a>
                        </td>
                    </tr>
                    </tbody>
    $scope.editSec = function (event,id,context) {
            if(angular.element(event.target).context.innerHTML == "编辑"){
                angular.element(event.target).parents("tbody").find("input").attr("readonly","readonly");
                angular.forEach(angular.element(event.target).parents("tbody").find("input"),function (data, index, array) {
                    angular.element(angular.element(data).parents("tr").find("a")[0]).context.innerHTML = "编辑";
                })
                $scope.checkEdit = false;
                angular.element(event.target).parents("tr").find("input").removeAttr('readonly').focus();
                angular.element(event.target).context.innerHTML = "保存";
    
            }else{
                $scope.updateCor(id,context);
                $scope.checkEdit = true;
                angular.element(event.target).parents("tr").find("input").attr("readonly","readonly");
                angular.element(event.target).context.innerHTML = "编辑";
    
            }
    
        }
  • 相关阅读:
    单例设计静态内部类
    maven中指定jdk编译版本
    带你十天轻松搞定 Go 微服务之大结局(分布式事务)
    微服务从代码到k8s部署应有尽有系列(五、民宿服务)
    微服务从代码到k8s部署应有尽有系列(三、鉴权)
    微服务从代码到k8s部署应有尽有系列(八、各种队列)
    微服务从代码到k8s部署应有尽有系列(七、支付服务)
    微服务从代码到k8s部署应有尽有系列(一)
    带你十天轻松搞定 Go 微服务系列(九、链路追踪)
    微服务从代码到k8s部署应有尽有系列(六、订单服务)
  • 原文地址:https://www.cnblogs.com/yangfei-beijing/p/6593864.html
Copyright © 2020-2023  润新知