AngularJS,在后退按钮上使用没有刷新的路由

我正在使用angularJS使用AJAX构建一个简单的单页面应用程序,但是当用户使用本机后退按钮时,我遇到了问题。

 angular.module('myApp', ['ionic', 'myApp.controllers', myApp.services]) .config(function ($routeProvider, $locationProvider) { $routeProvider.when('/home', { templateUrl: 'templates/feed.html', controller: 'MenuCtrl', reloadOnSearch: false }); $routeProvider.when('/checkin/view/:id', { templateUrl: 'templates/checkin.html', controller: 'MenuCtrl' }); $routeProvider.otherwise({ redirectTo: '/home' }); $locationProvider.html5Mode(true) }) 

更新:每个反馈移出$ http控件,并提出建议:

和我的services.js文件:

 angular.module('myApp.services', []) .factory('FeedService', ['$http', function($http){ var state = {}; var loadFeed = function(){ $http({ method: 'GET', url: 'http://api.example', }).success(function(data){ // With the data succesfully returned, call our callback state = data.response; console.log(data); }).error(function(){ alert("error"); }); }; loadFeed(); return { getState: function(scope){ return state; } }; }]) 

和我的controller.js文件:

 angular.module('myApp.controllers', []) .controller('MenuCtrl', function($scope, $http, $location, FeedService) { // feedback per second answer $scope.items = FeedService.getState(); }) .controller('CheckinCtrl', function($scope, $routeParams) { $scope.checkin_id = $routeParams.id; console.log($routeParams.id); }); 

我的主要index.html设置如下:

   

这从导航(/home)导航到签到页面(/checkin/view/:id)但是,一旦用户点击浏览器上的本机后退按钮或使用window.history.back() ,再次调用controller代码,这使得AJAX调用下拉用户的朋友提要。 我是否应该使用ng-show而不是使用ng-view作为此用例,并为我想要显示的每个内容创建单独的“页面”? 我关注的是性能,但似乎无法在每个ng-view保留数据而不必重新调用模板。 这里有什么指导?

更新:通过在services级别添加$http请求而不是controller级别,我已将此更改为包含最佳实践。 $http的AJAX完成之前,我仍然遇到了被触发的getState请求的问题,因此具有空状态,并且没有呈现$scope

是的,后退按钮和刷新按钮是一个真正的痛苦。 你有两个选择:

  1. 您可以保持简单,只需为每个位置更改提取状态。 这会将用户触发的后退按钮单击或刷新视为任何正常位置更改。 可以通过http缓存来减轻数据重新获取。

  2. 您在客户端上维护自己的状态并在需要时恢复它,可能使用SessionStorage来保持清洁。

我选择了后一个选项,它对我来说都很好。 有关详细的代码示例,请参阅这些自答问题。

  • 如何让后退按钮与AngularJS ui-router状态机一起使用?
  • 如何使用AngularJS单页面应用程序处理页面刷新

使用服务来保持单例状态,这会将函数暴露给get / reload / etc. 这是一个非常简单的例子,只是为了让你开始:

 .factory('FeedService', ['$http', function($http){ var state = {}; var loadFeed = function(){ $http.get('http://api.example.com').then(function(result){ state.feed = result.items; }); }; // load the feed on initialisation loadFeed(); return { getState: function(){ return state; } }; }]) .controller('MenuCtrl', ['$scope', 'FeedService', function($scope, FeedService) { // assign the feed container to any scope that you want to use for view $scope.cont = FeedService.getState(); }) 

同样,这是非常基本的,只是向您展示如何使用服务在路由之间存储持久状态。

如果路由中的参数“id”包含在http请求期间正在解码的任何字符(例如“=>’%20’),那么您的路由将不起作用。 尝试在字符串上执行encodeURIComponent(),然后再将其用于路由。