UI-Router - Change $state without rerender/reload of the page

angular-ui-router, angularjs

Solution

For this problem, you can just create a child state that has neither `templateUrl` nor `controller`, and advance between `states` normally:

// UPDATED
$stateProvider
    .state('schedules', {
        url: "/schedules/:day/:month/:year",
        templateUrl: 'schedules.html',
        abstract: true, // make this abstract
        controller: function($scope, $state, $stateParams) {
            $scope.schedDate = moment($stateParams.year + '-' + 
                                      $stateParams.month + '-' + 
                                      $stateParams.day);
            $scope.isEdit = false;

            $scope.gotoEdit = function() {
                $scope.isEdit = true;
                $state.go('schedules.edit');
            };

            $scope.gotoView = function() {
                $scope.isEdit = false;
                $state.go('schedules.view');
            };
        },
        resolve: {...}
    })
    .state('schedules.view', { // added view mode
        url: "/view"
    })
    .state('schedules.edit', { // both children share controller above
        url: "/edit"
    });

An important concept here is that, in `ui-router`, when the application is in a particular state—when a state is "active"—all of its ancestor states are implicitly active as well.

So, in this case,

- when your application advances from view mode to edit mode, its parent state `schedules` (along with its `templateUrl`, `controller` and even `resolve`) will still be retained.

- since ancestor states are implicitly activated, even if the child state is being refreshed (or loaded directly from a bookmark), the page will still render correctly.

Problem

I've been looking at these pages (1, 2, 3). I basically want to change my `$state`, but I don't want the page to reload. I am currently in the page `/schedules/2/4/2014`, and I want to go into edit mode when I click a button and have the URL become `/schedules/2/4/2014/edit`. My `edit` state is simply `$scope.isEdit = true`, so there is no point of reloading the whole page. However, I do want the `$state` and/or `url` to change so that if the user refreshses the page, it starts in the edit mode. What can I do?

Original source

Related problems