Angular ui-router-extras Chris answer

sticky states that force each other out

by Kyrylo Slatin

HTML

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.js"></script>
<script src="https://rawgit.com/christopherthielen/ui-router-extras/master/release/ct-ui-router-extras.js"></script>
<script src="https://rawgit.com/angular-ui/ui-router/c3d543aae43d4600512520a0d70723ac31f2cb62/release/angular-ui-router.js"></script>
<div ng-controller="ctrl">
    {{currentUrl}}
    <ui-view></ui-view>
    <ui-view name="stuck" ng-show="showSticky"></ui-view>
    <p>There are three states: <code>sticky1, sticky2</code> and <code>modal</code>. <code>Sticky 1/2</code> being two  <code>sticky:true</code> preemtive states and <code>modal</code> an ordinary state on the same level</p>
    <p><i>Preemtive</i> means they occupy same named <code>ui-view</code> and thus should force out each other when switched <code>sticky1 -> sticky2</code> or <code>sticky2 -> sticky1</code></p>
        <p>However there is an issue in "[email protected]" which erases <i>stickiness</i> after first replacement of sticky state in its view</p>
    <p>When user switches between <code>modal</code> and first instance of a sticky state <code>modal</code> controller and view are recreated each time. However <code>sticky</code> stays the same</p>
    <p>But when <code>sticky1</code> is replaced with <code>sticky2</code> these states will be recreated each time when switching with <code>modal</code>. Even if user returns to <code>sticky1</code> </p>
    <p></p>
    <p></p>
    <p></p>
    <code></code> 
</div>

<script type="text/ng-template" id="sticky1.html">
    <div >Sticky1 view {{id}} instance {{instanceCount}}</div>
    <button ui-sref="{id:2}">Sticky1: 2</button>
    <button ui-sref="sticky2">Sticky2</button>
    <button ui-sref="modal">Modal</button>
</script>

<script type="text/ng-template" id="sticky2.html">
    <div >Sticky2 view instance {{instanceCount}}</div>
    <button ui-sref="sticky1({id:1})">Sticky1: 1</button>
    <button...

CSS

code {
    color: #333;
}

JavaScript

angular.module('app', ['ui.router', 'ct.ui.router.extras']);
angular.module('app').config(function($stateProvider, $urlRouterProvider, $stickyStateProvider){
  //$stickyStateProvider.enableDebug(true);
    $stateProvider
    .state('stuck', {
        sticky: true,
        views: { stuck: {
            template: '<h1>stuck</h1><div ui-view></div>'
        }}
    })
    .state('sticky1', {
        url: '/sticky1/:id',
        parent: 'stuck',
        controller: 'sticky1Ctrl',
        templateUrl: 'sticky1.html'
    })
    .state('sticky2', {
        url: '/sticky2',
        parent: 'stuck',
        controller: 'sticky2Ctrl',
        templateUrl: 'sticky2.html'
    })
    .state('modal', {
        url: '/modal',
        controller: 'modalCtrl',
        templateUrl: 'modal.html'
    })
    ;
  $urlRouterProvider.otherwise("/sticky2");
});
angular.module('app').controller('ctrl', function($scope, $state){
    console.log('ctrl init');
    $scope.$on('$stateChangeSuccess', function(st){
        $scope.currentUrl = $state.href($state.current.name, $state.params);
        console.log('switched to state: ' + $state.current.name);
        $scope.showSticky = $state.includes('stuck');
    });
});
var sticky1Count = 0;
angular.module('app').controller('sticky1Ctrl', function($scope, $state){
    $scope.id = $state.params.id;
    $scope.instanceCount = sticky1Count++;
    console.log('sticky1Ctrl init ' + $scope.instanceCount);
});
var sticky2Count = 0;
angular.module('app').controller('sticky2Ctrl', function($scope){
    $scope.instanceCount = sticky2Count++;
    console.log('sticky2Ctrl init ' + $scope.instanceCount);
});
var modalCount = 0;
angular.module('app').controller('modalCtrl', function($scope, $previousState){
    $scope.instanceCount = modalCount++;
    console.log('modalCtrl init ' + $scope.instanceCount);
    $scope.goBack = function(){
        $previousState.go();
    };
});
angular.bootstrap(document, ['app']);