zoukankan      html  css  js  c++  java
  • angular常见坑洞

    由于版本不同,可能有些问题在某些版本下出现,某些版本下不出现.

    指令不可平行(v1.3.2):

    多个指令不能这样一个接着一个排下去:

    <div>
        <directive-one/>
        <directive-two/>
        <directive-three/>
    </div>    

    这样会导致的结果就是,只能读取<directive-one/>,后面的两个指令被自动无视掉~~~凭空消失鸟~~~

    解决办法: 每个指令放在一个div里

    <div>
        <directive-one/>
    </div>  
    <div>
        <directive-two/>
    </div>  
    <div>
        <directive-three/>
    </div>  

    还有个解决办法,把指令的restrict指定为EA,然后不要使用<directive/>这种形式,而是使用<div directive>这种形式.

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    变量名和模块名不能相同(v1.3.2):

    如下这样会报错,无法执行:

    var model = angular.module('model',[]);

    玫红色和墨绿色的两个名字不能相同,这个问题很少出现,应该是不会的.但是有一次确实遇到了...

    解决办法: 不说了...

    指令模板里面不能用出现指令名作为类名(v1.3.2):

    比如一个指令叫 <menu-bar/>

    那么,指令的模板里面,我不能再有 <div class="menu-bar">

    如果遇到这种情况,它会报错: $compile:multidir

    解决办法: 

    1.换不同的名字

    2.指令的restrict中去掉C值

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

    e.stopPropagation()阻止不了a链接的默认跳转事件(v1.3.2): 

    比如这样一段代码:

      <a href="http://www.baidu.com">
          <span ng-click="do($event)"></span>
      </a>
    $scope.do = function(e){
          e.stopPropagation();              
    }    

    这里我已经给do函数添加了阻止冒泡,但是a链接的跳转还是会触发的.

    解决办法: 使用 e.preventDefault();

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

    通过link函数中的iele来给元素绑定事件和通过ng-click(ng-...)等绑定事件的差异性(v1.3.2): 

    这个其实不是坑,只是使用上的一个注意点.什么意思呢? 

    就是说,指令的link属性第二个参数'iele',有时候我们可以通过$(iele).bind(),直接使用jq来给元素绑定事件:

    link: function(scope,iele){
         $(iele).find('input').bind('focus',function(){
              scope.flag = true       
         })
    }

    另外,我们也可以在html中使用 ng-click(ng-event...)等来绑定事件:

    <input ng-focus="changeFlag()">
    link: function(scope,iele){
         scope.changeFlag = function(){
               scope.flag = true
         }
    }

    那么什么时候使用第一种,什么时候使用第二种呢?

    是这样的,如果事件处理程序里,改变了当前scope下的属性值,也就是说,数据发生了改变,这个时候使用第二种,如果事件处理程序里,仅仅改变视图的显示(并非通过数据的改变来改变视图的显示),这个时候使用第一种.

    为什么呢? 因为使用第二种,是ng自己绑定的事件,在执行事件以后,ng会自动进行脏值检测($digest),而自己绑定的事件,ng是不会检测的(虽然我做的过程中发现有时候也会检测...⊙﹏⊙b汗),这样,scope下数据模型发生改变,是不会被检测到的,需要手动去调用$digest,虽然也可以实现,但是就不符合ng的设计模式了.

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

    给指令添加控制器时候的scope问题(v1.3.2):

    这个坑很大...一不小心陷入万丈深渊...

    比如有一个指令:

    <directive/>

    指令是这样定义的:

    module.directive('directive',function(){
          return {
                restrict:'E',
                replace:true,
                templateUrl:'index.html'
          }   
    })

    然后index.html是这样的:

    <div ng-controller="controllerOne">
        ...
    </div>

    定义控制器:

    module.controller('controllOne',function($scope){
        $scope.a = 'a'
    })

    这样,正常的理解就是directive指令这个div,使用controllerOne来管理,它的scope就是controllerOne里面的$scope.

    但是事实不是这样的,用这种方式定义的controller,$scope并非是一个单独的继承了父scope的scope,而是直接绑定在了根scope上!

    解决办法: 在指令元素上绑定ng-controller属性,而不是指令的html模板上:

    <directive ng-controller="controllerOne"/>

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

    使用ui-router路由切换时状态的事件(ui-router.min.js  v0.2.12)

    ui-router状态改变时会触发$stateChangeStart,$stateChangeSuccess,$viewContentLoading,$viewContentLoaded这些事件,但是这些事件不能绑定在状态的controller属性的控制器里:

    $stateProvider.state('index',{
            url:'/index',
            resolve:{
                rsv:'aService'
            },
            controller:function($rootScope,$scope,rsv){
                $scope.username = rsv.getName();
                $rootScope.$on('$viewContentLoading',function(event, viewConfig){
                    alert('视图开始渲染');
                });
                $rootScope.$on('$viewContentLoaded',function(){
                    alert('视图渲染完毕');
                })
            },
            templateUrl:'./tpls/login.html'
        });

    这样做,每次进入index状态,都会实例化一个控制器,都会绑定一次事件,这样,$viewContentLoading和$viewContentLoaded事件会越来越多.

    解决办法: 在外层的控制器的$rootScope里绑定事件.

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

    date过滤器:

    使用date过滤器过滤时间时,时间的值如果是数字或者字符串数字,这个数字不是时间戳,而是当前时间毫秒数.也就是时间戳*1000 

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

    使用ui-router路由的$urlRouterProvider无效(ui-router.min.js  v0.2.12)

    定义了一个路由,然后通过$urlRouteProvider来定义一个重定向: 当匹配到'/'的时候,重定向到'/all'

    flightApp.config(function($stateProvider,$locationProvider,$urlRouterProvider){
        $locationProvider.html5Mode(true).hashPrefix('!');
    
        $stateProvider.state('index',{
            url:'/:date',
            templateUrl:'tpls/flights.html',
            resolve:{
                'filterFlights':function($http,$stateParams){
                    return $http({
                        method:'get',
                        url:'cache/flights_'+($stateParams.date || 'all')+'.json'
                    });
                }
            },
            controller: 'fligntsControll'
        });

    $urlRouterProvider.when('/','/all');
    });

    但是这个重定向并没有实现,也没有任何报错.原因不详.

    解决办法:修改顺序,把$urlRouterProvider.when()这段代码移到$stateProvider.state()之前

    flightApp.config(function($stateProvider,$locationProvider,$urlRouterProvider){
        $locationProvider.html5Mode(true).hashPrefix('!');
    
        $urlRouterProvider.when('/','/all');
    
        $stateProvider.state('index',{
            url:'/:date',
            templateUrl:'tpls/flights.html',
            resolve:{
                'filterFlights':function($http,$stateParams){
                    return $http({
                        method:'get',
                        url:'cache/flights_'+($stateParams.date || 'all')+'.json'
                    });
                }
            },
            controller: 'fligntsControll'
        });
    });

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

  • 相关阅读:
    MySQL的删除语句
    机器学习-K-means聚类及算法实现(基于R语言)
    机器学习-线性回归补充-实践
    什么是JWT
    Java的NIO
    音乐播放器歌词同步显示
    Linux和Mac下安装RocketMQ过程
    支付宝沙箱应用
    HTML5 调用手机摄像头拍照
    JavaWeb图片上传的几种方式
  • 原文地址:https://www.cnblogs.com/liulangmao/p/4318229.html
Copyright © 2011-2022 走看看