angular常見坑洞

因爲版本不一樣,可能有些問題在某些版本下出現,某些版本下不出現.html

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

多個指令不能這樣一個接着一個排下去:json

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

這樣會致使的結果就是,只能讀取<directive-one/>,後面的兩個指令被自動無視掉~~~憑空消失鳥~~~設計模式

解決辦法: 每一個指令放在一個div裏ide

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

還有個解決辦法,把指令的restrict指定爲EA,而後不要使用<directive/>這種形式,而是使用<div directive>這種形式.函數

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ui

變量名和模塊名不能相同(v1.3.2):url

以下這樣會報錯,沒法執行:spa

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'
    });
});

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

相關文章
相關標籤/搜索