2016-06-11 69 views
0

我有一個指令,從其父控制器繼承範圍。該指令是一個覆蓋頁面三秒的div元素,然後消失,除非單擊上/下箭頭按鈕。 div元素是一種模態。這是對我的DOM使用超時顯示和隱藏自定義指令元素

HTML

<div ng-show="volumeVisibility"> 
    <display-volume-modal></display-volume-modal> 
</div> 

默認設置爲false的代碼。當volumeVisibility === true時,該指令將出現在點擊按鈕上。到現在爲止還挺好。這些是我在控制器中的兩個功能:

$scope.volumeVisibility = false; 

$scope.timer = function(){ 
    console.log("Timer"); 
    $scope.volumeVisibility = false; 
}; 

$scope.displayVolumeModal = function(){ 
    $scope.volumeVisibility = true; 
    console.log("modal"); 
}; 

超時工作並設置$scope.volumeVisibility === false。但是,div不會從頁面中移除。下面是從該指令的代碼(I已經刪除了不相關部分):

return { 
    restrict: 'E', 
    scope: false, 
    link: function(scope, elem, attrs){ 
     scope.$watch('volumeVisibility', function(newVal, oldVal){ 
      if (newVal === true){ 
       window.setTimeout(scope.timer, 3000);   
       document.addEventListener('keydown', function(e){ 
        //stuff 
        switch (e.which) {    
         case 38: 
          //stuff 
          break; 
         case 40: 
          //stuff 
          break; 
        } 
       }); 
      } 
     }, true); 
    }, 
    templateUrl: 'public/templates/displayVolumeModal.html' 
} 

我試圖將每個功能進指令或控制器。我可以採取什麼步驟使此指令DIV元素在超時後消失?

+0

你能提供'scope.timer'函數體嗎? –

+0

從第一眼便可以想到:嘗試將'ng-show'放在'display-volume-modal'內並擺脫'div' – ZenDD

回答

1

沒有發生任何事情,因爲沒有摘要循環被調用。

要更新同步,您必須運行摘要循環。我認爲,在這種情況下,您可以使用$timeout服務而不是setTimeout。

收益$超時服務:

  • 單元測試
  • $消化週期啓動功能後,你傳遞給超時
+0

你明白了!這是$超時服務!謝謝! –

+1

實際上,您可以使用其他方法調用摘要循環。像'scope'對象中的'$ evalAsync'方法,但我認爲這不是一個好的解決方案。 $超時 - 你需要什麼。另外,$ timeout可以在單元測試中輕鬆模擬 –

1

window.setTimeout(scope.timer, 3000);不叫角digest週期,所以watch沒有按」沒有看到變化。

使用角度的$timeout服務,而不是像這樣:

$timeout(scope.timer, 3000); 

在內部它一樣window.setTimeout,但可以確保,即digest會後調用。

閱讀更多關於angular digest cycle以及角度檢查是否有些變量發生了變化。特別是Integration with the browser event loop一章。

+0

你明白了!這是$超時服務!謝謝! –

0

如果您使用ng-show和ng-hide它只會簡單地隱藏它所應用的特定html元素的可見性。該元素將在DOM中,無論它是否隱藏或顯示。 這就是爲什麼指令沒有被調用。

如果你想將它出現在屏幕上的指令每次,只要使用NG-如果代替NG秀