2

I have a MainCtrl containing a backstack for history, like this;

$scope.urlHistory = [];

$scope.$on('$routeChangeSuccess', function () {
    if ($location.$$absUrl.split('#')[1] !== $scope.urlHistory[$scope.urlHistory.length - 1]) {
        $scope.urlHistory.push($location.$$absUrl.split('#')[1]);
    }
});

Then, in the same controller I've got a GoBack() function I'd like to call when the back button is pressed;

$scope.goBack = function () {
    $scope.urlHistory.pop();
    $location.path($scope.urlHistory[$scope.urlHistory.length - 1]);
};

This is supposed to work because from my index.html I call it with ng-click="goBack()" and everything works as expected.

I use this for the device events, same controller;

function onBackKeyDown() {
  alert("back");
  $scope.goBack();
}

document.addEventListener("deviceready", onDeviceReady, false);
// device APIs are available
//
function onDeviceReady() {
  // Register the event listener
  alert("deviceready");
  document.addEventListener("backbutton", onBackKeyDown, false);
};

I can see the alerts, but the app's not navigating back. Something happens though, because if I press the device back button twice, the ng-click="goBack()" suddenly takes me back to the start page of the app. Am I using $scope wrong? Experiencing this on Win Phone & Android. Using Phonegap Build.

edit: What I'm really after here is why would my $scope.goBack(); function work differently when called from the devicelistener.

3
  • What is the overall purpose of this code? Is it just to navigate to the previous page when the user clicks the back button? Commented Apr 10, 2014 at 19:06
  • Sorry if that was unclear, that's exactly what the purpose is indeed. Commented Apr 10, 2014 at 19:32
  • I know a bit better what is going wrong. $location.path(); does not work when invoked by the event listener. Calling it with ng-click works fine. Commented Apr 21, 2014 at 12:49

2 Answers 2

1

This solved it:

  $scope.goBack = function () {
    if (urlHistory == '/') { 
      document.removeEventListener("backbutton", onBackKey, false);

    };    
    urlHistory.pop();
    $location.path(urlHistory[urlHistory.length - 1]);
    $scope.$apply();
  };

The scope.$apply(); was my answer. It's necessary when executing angular expressions outside of angular. (AngularJS $location not changing the path)

Sign up to request clarification or add additional context in comments.

Comments

0

You should be able to just use the browser's built-in history object for this. For example:

function onDeviceReady() {
    document.addEventListener("backbutton", function () {
        window.history.go(-1);
    });
}

You shouldn't need to do anything specific just because you're using angular. Unless I'm missing something else...

UPDATE: After looking at the phonegap docs, it looks like the default backbutton behavior already does what you want... or are you trying to do something special?

2 Comments

You're right, except the default back button behaviour for Windows Phone (8) seems to be exiting the app. That's why I'm using my own "history object". Also, window.history.go(-1) does not work on Windows Phone.
Ok, sorry. Whenever I've done phonegap development I've only ever targeted iOS and Android so I'm not familiar with windows phone quirks. But the principle should be the same. Whatever cross-platform code that will go back in the browser's history should go in the "backbutton" listener. See this post for more info.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.