2017-03-09 52 views
0

我正在嘗試創建一個2控制器和2個服務的簡單示例,其中每3秒調用一個服務。無法綁定setInterval操作的值

控制器1調用服務,該服務更改控制器2中使用的值。我通過另一個服務傳遞值,但只有在按下示例中的「停止」按鈕(在波紋管中)後,該值纔會在我的html頁面上更新。

我可以更新每次投票的頁面值嗎?

<html ng-app="myApp"> 
<head> 
    <title>MyApp</title> 
    <script src="angular.js"></script> 
    <script> 
     var app = angular.module('myApp',[]); 


     app.service('SimpleService', function() { 

      var _value = 0; 

      var setValue = function(v) { 
       _value = v; 
      } 

      var getValue = function(){ 
       return _value; 
      } 

      return { 
      setValue: setValue, 
      getValue: getValue 
      }; 
     }) 

     app.service('PollService', function(SimpleService) { 

      var poll = undefined; 


      var startPolling = function(){ 

       poll = setInterval(function(){ 
        console.info('poll...'); 
        console.info(SimpleService.getValue()); 
        SimpleService.setValue(SimpleService.getValue()+1); 

       }, 3000); 

      } 

      var stopPolling = function(){ 
       clearInterval(poll); 
      } 


      return { 
      startPolling: startPolling, 
      stopPolling: stopPolling 
      }; 
     }) 


     app.controller('Controller1',function($scope, PollService){ 
      var poll = undefined; 


      $scope.startPolling = function(){ 
       PollService.startPolling(); 
      } 

      $scope.stopPolling = function(){ 
       console.info('stop'); 
       PollService.stopPolling(); 
      } 

     }); 


     app.controller('Controller2', function($scope, SimpleService){ 
      $scope.newVal = function(){ 
       return SimpleService.getValue(); 
      }    
     }); 
    </script> 

</head> 

<body> 
    <div ng-controller="Controller1"> 
     <button ng-click="startPolling()">Start</button> 
     <button ng-click="stopPolling()">Stop</button> 
     <br/> 
     <br/> 

    </div> 
    <div ng-controller="Controller2"> 
      <h5>New value: {{newVal()}}</h5> 
     </div> 

</body> 

問候。

+2

https://docs.angularjs.org/api/ng/service/$interval – sh0ber

+2

與[本問題](http:// stackoverflow。com/questions/42701048/how-to-pass-vm-to-a-settimout-in-angularjs)在這裏應用。在這種情況下使用[$ interval](docs.angularjs.org/api/ng/service/$interval)作爲@ sh0ber提到 – lealceldeiro

+0

PollService.stopPolling()的代碼在哪裏? –

回答

1

由於setInterval的是不是一個角功能,角度不知道該值被更新並且不能告訴DOM該值是髒的,因此不會被更新。

如果你想繼續使用setInterval而不是角的$區間,你可以注入$rootScope到您的輪詢服務,然後你可以使用$rootScope.$apply消化將更新DOM的價值。你可以做

$rootScope.$apply(function(){ 
    SimpleService.setValue(SimpleService.getValue()+1); 
}); 

你的setInterval函數裏面。

否則,$intervalsetInterval函數的angular.js包裝器,它不需要手動調用$ apply。

我對您的代碼和一些示例進行了更改,以瞭解如何更好地在控制器範圍內使用服務。

See here for updated code

主要是,由於服務是一個對象,我們可以直接通過將服務本身到控制器範圍,而不是參考的個體對象鍵引用該服務的上下文中DOM。這消除了從DOM調用getter函數的需要(就像您在調用{{newValue()}}時一樣)。

3

您需要在每次調用SimpleService中的setter時調用摘要循環。視圖綁定不會更新,除非重新啓動一個摘要循環。這是工作代碼片段。

app.service('SimpleService', function($rootScope) { 

     var _value = 0; 

     var setValue = function(v) { 
      _value = v; 
      $rootScope.$apply(); //added this here 
     } 

     var getValue = function(){ 
      return _value; 
     } 

     return { 
     setValue: setValue, 
     getValue: getValue 
     }; 
    }) 

您需要做scope.apply()。 $ apply將評估模板中的任何表達式並啓動一個新的摘要循環。在$ digest階段,範圍將檢查所有$ watch表達式並將它們與先前的值進行比較。您可以結帳關於它的文檔here

我在你的代碼注意到一些其他問題:

app.controller('Controller2', function($scope, SimpleService2){ 
    $scope.newVal = function(){ 
    return SimpleService.getValue(); 
    }    
}); 

這裏,改正名稱SimpleService。

沒有爲stopPropagation.I沒有方法添加它作爲PollService如下得到您的代碼工作:

var stopPolling = function(){ 
    clearInterval(poll); 
}