I'm creating an Angular mobile SPA app and part of the requirements have a substantial amount of list >> details pages. After they filter to populate the list, they can click on the item to go to a details page for it (with crud options if allowed, which rules out just using a modal). I'm saving the relevant data and things in a service, but this does not help maintain the scroll position and ui-router-extras sticky state seems like it would be ideal. I'm using requirejs as well, in case that's relevant. Also, I am using a Kendo ListView bound with a kendo.dataSource if that is relevant.
I've implemented it, but I'm not sure I've done it correctly. I scroll down and click on a list item and it goes to the details. When I click the back button (a directive that uses $window.history.back();
, although I tried using $state.go
and it did the same thing), it will go back and used the "cached" version, but will be at the top of the list. If I scroll down and click on another item and then go back, it will maintain the scroll position like I expect.
I turned on $stickyStateProvider.enableDebug(true);
and the output looks identical from the first to the subsequent calls.
Here's my states config:
return app.config(function ($stateProvider, $stickyStateProvider, $urlRouterProvider) {
$stickyStateProvider.enableDebug(true);
$urlRouterProvider.otherwise(function ($injector, $location) {
var $state = $injector.get("$state");
$state.go("home");
});
$stateProvider.state('home', {
url: '/home',
templateUrl: 'app/views/home.html',
controller: 'homeController',
controllerAs: "vm"
})
.state('cmmenu', {
url: '/cmmenu',
templateUrl: 'app/views/cmmenu.html',
controller: 'cmmenuController',
controllerAs: "vm"
})
.state('areainquiry', {
//sticky: true,
abstract: true,
url: '/areainquiry',
templateUrl: 'app/views/areainquiry.html'
})
.state('areainquiry.list', {
url: '/areainquirylist',
views: {
'areainquirylist@areainquiry': {
templateUrl: 'app/views/areainquirylist.html',
controller: 'areainquirylistController',
controllerAs: "vm"
}
},
sticky: true,
deepStateRedirect: true
})
.state('areainquiry.details', {
url: '/areainquirydetails/:areaInquiryId',
views: {
'areainquirydetails@areainquiry': {
templateUrl: 'app/views/areainquirydetails.html',
controller: 'areainquirydetailsController',
controllerAs: "vm"
}
}
})
.state('login', {
url: '/login',
templateUrl: 'app/views/login.html',
controller: 'loginController',
controllerAs: "vm"
});
})
Here is the areainquiry.html that is the abstract parent view:
<div ui-view="areainquirylist" ng-show="$state.includes('areainquiry.list')"></div>
<div ui-view="areainquirydetails" ng-show="$state.includes('areainquiry.details')"></div>
Here is the code that is opening this screen. I do not have a named view in my index.html and all views up to areainquiry.html are using the root un-named view (I gave it a name "body" and changed all of them to use it, but it worked the same):
<div class="col-xs-6 col-md-4">
<a class="btn btn-default fullwidth" ui-sref="areainquiry.list">
<span class="{{ vm.areaInquiryButtonIcon }}"></span>
<br />
{{ vm.areaInquiryButtonText }}
</a>
</div>
I was trying to figure out a way to do it without the abstract state and just through a parent areainquiry and child areainquiry.detail, but couldn't get it working that way, so went this route.
Never mind. It is working. I'm not sure how I fixed it. I was working through another issue (had to do with a factory service), so I'm assuming that fixed it.