简体   繁体   中英

Angularjs view doesn't update

I'm trying to update a view through a controller that sources its data from a service. For some reason, the view doesn't update when the service's data changes. I've distilled an example from my application here . I've tried all sorts of bindings ( $scope.time = TimerService.value , wrapped in a function, using $watch - no success).

Note, in my original app, this is an array of objects and an object's attribute changes.

-- script.js --

var mod = angular.module('mymodule', []);

mod.service('TimerService', function() {
  this.value = 0;
  var self = this;
  setInterval(function() {
    self.value += 1;
  }, 2000)
});

mod.controller('TimerCtrl', ['TimerService', '$scope', function(TimerService, $scope) {
  $scope.time = TimerService.value;
  $scope.$watch(function() {
    return TimerService.value;
  }, function(newValue) {
    $scope.time = newValue;  
  }, true);
  $scope.otherValue = '12345';
}]);


angular.element(document).ready(function() {
  alert('start');
  angular.bootstrap(document, ['mymodule']);
});

-- index.html --

<!DOCTYPE html>
<html>

  <head>
    <script src="./angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
      <div ng-controller="TimerCtrl">
          <h1>- {{ time }}-</h1>
          <h2>{{ otherValue }}</h2>
      </div>
  </body>

</html>

After spending some time with trial and error, I finally found the answer to the problem. In my example above (and my real application), the data gets changed outside of the angular scope (controller button click, http request, etc) which means a digest cycle is not getting kicked off. If I change the code to use $timeout() , it works. Unfortunately, this doesn't entirely solve my problem of the data being changed outside of angular (I guess I need to integrate the rest into angular as well).

Update

I managed to perform changes outside of angular by using rootscope in my service:

$rootscope.$apply(function() {
  // perform variable update here.
  self.value += 1;
});

This successfully propagates to the view.

Try this

$scope.time = TimerService.value;
if(!$scope.$$phase) {
    $scope.$apply();
}

Try

var app = angular.module('myApp', []);
            var value = 0;
            var timer = setInterval('Repeater()', 1000);
            var Repeater = function () {
                value++;
                var scope = angular.element(document.getElementById('myApp')).scope();
                console.log(scope);
                scope.$apply(function () {
                        scope.time = value;
                    });
                };
            app.controller('TimerCtrl', ['$scope', function( $scope) {

          }]);

credit to https://stackoverflow.com/a/16520050/356380

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM