简体   繁体   中英

AngularJS + Ionic is truncating scope value after the return from second page to the main page.

I have following code in the "First" Ctrl of the my app, which is displaying timer for countdown.

Everything is working absolutely fine until i visited second page which is in the app.js defined by this way:

  .state('app.home', {
      url: '/home:playlistData',
      views: {
        'menuContent' :{
          templateUrl: 'templates/home.html',
          controller: 'HomeCtrl'
        }
      }
    })

    .state('app.saved', {
      url: '/saved',
      views: {
        'menuContent' :{
          templateUrl: 'templates/saved.html',
          controller: 'SavedCtrl'
        }
      }
    })

If i came back from second view to the first counter is still displayed but value in the

$scope.minutesLeft

Is not updated but

setInterval

function is still executing the code in the background and updated data values are still holded in the Dataholdingservice.

I tried scope apply and timeout functions, but without the luck.

Could somebody tell me how can i solve this issue?

Many thanks for any help.

Code of the HomeCtrl for countdown timer is following:

 $scope.setTimer = function(timer) {
        console.log(timer);
        $scope.timer = timer;
    };

    $scope.saveTimer = function(timer) {
        if($scope.selectedSounds.length == 0) {
            $scope.showAlert("Add some sounds", "Cannot run timer for empty list");
        } else {
            $scope.clearCountDownAnimation();
            var animationTimerId = setInterval(function () {
                $("#minutesLeft").fadeTo(100, 0.1).fadeTo(200, 1.0);
            }, 1000);
            Dataholdingservice.setAnimationId(animationTimerId);
            Dataholdingservice.setMinutesLeft(timer);
            $scope.closePopover();
            $scope.countDown();

        }
    };

    $scope.clearCountDownAnimation = function() {
        $("#minutesLeft").clearQueue().finish();
        // Clear previously set animations
        console.log(Dataholdingservice.getAnimationId());
        if (Dataholdingservice.getAnimationId() != null) {
          console.log("Interval cleared");
          clearInterval(Dataholdingservice.getAnimationId());
        }
    };

    $scope.countDown = function() {
            var minutesLeft = Dataholdingservice.getMinutesLeft();
            $scope.minutesLeft = minutesLeft;
            $scope.isCounterDisplayed = Dataholdingservice.isCounterDisplayed();
            var timerId = setInterval(function() {
            console.log("Counting down");
            minutesLeft -- ;
            console.log("Decreasing minutes");
            console.log(minutesLeft);
            Dataholdingservice.setMinutesLeft(minutesLeft);
            console.log("minutes left " + Dataholdingservice.getMinutesLeft());
            $scope.$apply(function () {
              $scope.minutesLeft = Dataholdingservice.getMinutesLeft();
            });

              if(minutesLeft <= 0) {
                  console.log("Time left");
                  clearInterval(Dataholdingservice.getTimerId());
                  clearInterval(Dataholdingservice.getAnimationId());
                  console.log(Dataholdingservice.isCounterDisplayed());
                  $scope.hideCounter();
                  $scope.stopAllSelectedSounds();
              }

            }, 1000 * 1);

            Dataholdingservice.setTimerId(timerId);
    };

    $scope.hideCounter  = function() {
        console.log("Hidding the counter");
        $scope.isCounterDisplayed = false;
        $scope.$apply();
    };

    $scope.cancelTimer = function() {
        clearInterval(Dataholdingservice.getTimerId());
        clearInterval(Dataholdingservice.getAnimationId());
        $("#minutesLeft").hide();
        $ionicLoading.show({
          duration: 500,
          template: 'Timer canceled'
        });
    };

Since the $scope.minutesLeft is a primitive datatype, sometimes the changes happening in the controller will not get reflected in the view. You can create an object like $scope.viewModel = {} and then add the minutesLeft as a property to it like $scope.viewModel.minutesLeft = mintesLeft in your countdown function and bind viewModel.minutesLeft to the view. you should see the value getting updated properly.

I am not sure of your exact requirement, but I have put together the code for creating a simple timer that runs in the background in an angular service. The working code is available at http://codepen.io/svswaminathan/pen/MYXOPM

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