2015-04-18 16 views
6

Pracuję ze stroną z AngularJS i muszę wyświetlić zegar działający w polu tekstowym wejściowym tylko do odczytu (dwukierunkowo związany z data-ng-model).Aby zasymulować działający zegar, Używam harmonogramu JavaScript z setTimeout do wywoływania funkcji co 1000 milisekund, co aktualizuje wartość właściwości $ scope'd, która z kolei jest powiązana z tym wejściowym polem tekstowym. W jakiś sposób wartość w polu wejściowym nie jest aktualizowana. umieścił znacznik <pre /> i zaktualizował jego zawartość przy użyciu selektora jQuery.To działa dobrze, więc potrzebuję pomocy w otrzymywaniu wartości pola tekstowego wejściowego, aby również aktualizować się co sekundęPole wejściowe AngularJS nie aktualizuje się z setTimeout wewnątrz kontrolera

Dla tego przykładu ustawiłem jsFiddle.

HTML jest poniżej:

<body data-ng-app="formApp"> 
    <div data-ng-controller="FormCtrl"> 
     Current Date and Time <input type="text" data-ng-model="formData.currentDateTime" readonly="readonly" size="60" /> 
    </div> 
    <pre id="currentDateTime" style="font-size:1.5em;"> 
    </pre> 
</body> 

W angularjs moduł aplikacji i kontroler są zadeklarowane w następujący sposób:

(function() { 
    var formApp = angular.module("formApp", []); 

    formApp.controller("FormCtrl", function ($scope) { 
     $scope.formData = {}; 
     $scope.formData.currentDateTime = new Date().toString(); 

     (function updateCDT() { 
      $scope.formData.currentDateTime = new Date().toString(); 
      document.getElementById("currentDateTime").innerHTML = $scope.formData.currentDateTime; 
      setTimeout(updateCDT, 1000); 
     })(); 
    }); 
})(); 

Odpowiedz

8

trzeba użyć $scope.$apply() lub angulars $timeout celu odzwierciedlenia zmian od setTimeout jest poza zakres angularjs

za pomocą $ scope. $ apply()

zastosować $ zakres. $ Apply() wewnątrz anonimowej funkcji setTimeout (function() {}, 1000), a następnie połączyć się z rzeczywistą funkcję jak poniżej

(function updateCDT() { 
     $scope.formData.currentDateTime = new Date().toString(); 
     document.getElementById("currentDateTime").innerHTML 
    = $scope.formData.currentDateTime; 
     setTimeout(function(){ 
      $scope.$apply(); 
      updateCDT() 
     }, 1000); 

fiddle dla $ zakresu. $ Apply()

użyciu $ limit czasu (nie zapomnij, aby wprowadzić go do kontrolera)

(function updateCDT() { 
      $scope.formData.currentDateTime = new Date().toString(); 
      document.getElementById("currentDateTime").innerHTML 
    = $scope.formData.currentDateTime; 
      $timeout(updateCDT, 1000); 

     })(); 

fiddle do $ ti meout

+0

Poszedłem z wtryskiem '$ timeout' do kontrolera i użyłem go, ponieważ wygląda na czystszy ** i **, ponieważ narzędzia dla programistów Chrome pokazują błąd' Błąd: [$ rootScope: inprog] $ apply already in progress' when używając '$ scope. $ apply();'. Dzięki za natychmiastową pomoc! –

+0

@WebUser zaktualizowany, teraz nie dostaniesz tego błędu. –

2

Jeśli modyfikujesz zakres poza zakrzywionym, jak przy setTimeout, musisz zadzwonić pod numer $scope.$apply.

+0

Narzędzia programistów Chrome wyświetlają komunikat o błędzie 'Błąd: [$ rootScope: inprog] $ apply already in progress' podczas używania' $ scope.$ apply(); ', więc poszedłem z' $ timeout'. –

+1

@WebUser Możesz użyć opcji 'if (! $ Scope. $$ phase) { // zadzwoń $ apply }' – jcubic

+1

@WebUser lub możesz zastosować $ scope. $ Apply() w anonimowej funkcji setTimeout (function() {$ scope. $ apply(); updateCDT()}, 1000), a następnie zadzwoń do rzeczywistej funkcji –

3

Zamiast setTimeout() można użyć $timeout() który wezwie $apply() wewnętrznie co mówi kątowe do prowadzenia likwidacji.

Wystarczy pamiętać, aby wstrzyknąć $timeout jako zależność

DEMO

2

prostu zrobić tak samo jak w tagu pre:

document.getElementById("input-field").value=$scope.formData.currentDateTime; 

Nadzieję, że to pomaga!

+0

Myślę, że mogłem to zrobić, ale chciałem zrobić to w sposób AngularJS :-) Dzięki za sugestię. –

Powiązane problemy