web-dev-qa-db-fra.com

AngularJS, utilisation d'itinéraires sans actualisation au bouton de retour

J'utilise angularJS pour créer une application simple à page unique en utilisant AJAX, mais je rencontre un problème lorsque les utilisateurs utilisent le bouton de retour natif.

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)

})

UPDATE: déplacement de $ http en dehors des contrôles par feedback et suggestions:

Et mon fichier 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;
       }
    };
}])

Et mon fichier 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);
});

Mon index.html principal est configuré comme ceci:

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

Cela fonctionne très bien de la navigation d’un fil (/home) à une page d’enregistrement (/checkin/view/:id), mais une fois que l’utilisateur a appuyé sur le bouton de retour natif du navigateur ou en utilisant window.history.back(), le code de la controller est rappelé, ce qui rend le AJAX appelez pour extraire le flux d'amis de l'utilisateur. Devrais-je utiliser ng-show au lieu d'utiliser ng-view pour ce cas d'utilisation et créer des "pages" individuelles pour chaque contenu que je souhaite afficher? La performance m'inquiétait, mais il semble que je ne parviens pas à conserver les données dans chaque ng-view sans qu'il soit nécessaire de rappeler les modèles. Des conseils ici?

UPDATE: J'ai changé cela pour incorporer les meilleures pratiques, en ajoutant la demande $http au niveau services, au lieu du niveau controller. Je rencontre toujours le problème de la demande getState en cours de lancement, avant que le AJAX du $http soit terminé, donc dans un état vide et ne permet pas de restituer le $scope.

10
gregavola

Oui, le bouton Précédent et le bouton Actualiser sont une vraie douleur. Vous avez deux choix:

  1. Vous gardez les choses simples et permettez que votre état soit récupéré à chaque changement d'emplacement. Ceci traite un clic du bouton de retour ou un rafraîchissement déclenché par l'utilisateur comme un changement d'emplacement normal. La récupération de données peut être atténuée par la mise en cache http.

  2. Vous conservez votre propre état sur le client et le restaurez si nécessaire, en utilisant éventuellement SessionStorage pour garder les choses propres.

J'ai choisi cette dernière option et tout fonctionne parfaitement pour moi. Voir ces questions à réponse automatique pour des exemples de code détaillés.

5
biofractal

Utilisez un service pour conserver un état singleton, qui expose les fonctions pour obtenir/recharger/etc. Voici un exemple très simple, juste pour vous aider à démarrer:

.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();
})

Encore une fois, ceci est très basique et montre simplement comment vous pouvez utiliser un service pour stocker un état persistant entre les itinéraires.

1
Matt Way

si votre paramètre 'id' dans la route contient un caractère décodé pendant la requête http (comme '' => '% 20'), votre route ne fonctionnera pas. votre chaîne avant de l’utiliser pour le routage.

0
silver