2016-06-11 82 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秀