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

时间:2014-05-04 15:19:13

标签: jquery ajax angularjs angular-routing

我使用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设置如下:

 <body ng-app="untappd">
   <div ng-view></div>
 </body>

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

更新:我已将此更改为合并最佳做法,方法是在$http级别添加services请求,而不是controller级别。在$http的AJAX完成之前,我仍然遇到了被触发的getState请求的问题,因此具有空状态,并且没有任何内容可以呈现$scope < / p>

3 个答案:

答案 0 :(得分:5)

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

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

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

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

答案 1 :(得分:1)

使用服务来保持单例状态,这会将函数暴露给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();
})

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

答案 2 :(得分:0)

如果你的参数&#39; id&#39;在路由中包含在http请求期间正在解码的任何字符(例如&#39;&#39; =&gt;&#39;%20&#39;)然后您的路由将无法正常工作。 尝试在字符串上执行encodeURIComponent(),然后再将其用于路由。