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 настроен следующим образом:

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

Это отлично работает с навигацией из фида (/home), на страницу регистрации (/checkin/view/:id), но после того, как пользователь нажмет на кнопку "назад" в браузере или с помощью window.history.back(), код в controller снова вызываемый, что заставляет вызов AJAX вытаскивать фид друга пользователя. Должен ли я использовать ng-show вместо использования ng-view для этого случая использования и создавать отдельные "страницы" для каждого содержимого, которое я хочу показать? Я был заинтересован в производительности, но, похоже, я не могу заставить данные сохраняться в каждом ng-view без необходимости повторного вызова шаблонов. Какие-нибудь рекомендации здесь?

UPDATE: я изменил это, чтобы включить Best Practices, добавив запрос $http на уровне services вместо уровня controller. Я все еще сталкиваюсь с проблемой запуска запроса getState до завершения AJAX $http, имея при этом пустое состояние и ничего не отображая $scope.

Ответ 1

Да, кнопка "Назад" и кнопка "Обновить" - настоящая боль. У вас есть два варианта:

  • Вы сохраняете все просто и просто позволяете своему государству получать выборку для каждого изменения местоположения. Это относится к нажатию кнопки нажатой кнопки пользователя или обновлению, как и любое обычное изменение местоположения. Повторная выборка данных может быть уменьшена путем кэширования http.

  • Вы сохраняете свое собственное состояние на клиенте и восстанавливаете его, когда требуется, возможно, используя SessionStorage, чтобы все было в порядке.

Я выбрал последний вариант, и все это отлично работает для меня. См. Ответы на собственные вопросы для подробных примеров кода.

Ответ 2

Используйте службу, чтобы сохранить одноэлементное состояние, которое предоставляет функции для получения/перезагрузки/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();
})

Опять же, это очень просто и просто показывает вам, как вы можете использовать службу для хранения постоянного состояния между маршрутами.

Ответ 3

если ваш параметр 'id' в маршруте содержит любой символ, который декодируется во время HTTP-запроса (например, '' = > ' %20'), тогда ваш маршрут не будет работать. попробуйте выполнить команду encodeURIComponent() в строке, прежде чем использовать ее для маршрутизации.