79 votes

Mise à jour de l'URL dans Angular JS sans refaire la vue

Je construis un système de tableau de bord en AngularJS et je rencontre un problème avec le paramétrage de l'url via $location.path

Dans notre tableau de bord, nous avons un tas de widgets. Chacun d'entre eux affiche une vue agrandie et maximisée lorsque vous cliquez dessus. Nous essayons de mettre en place des liens profonds pour permettre aux utilisateurs d'accéder à un tableau de bord avec un widget agrandi.

Actuellement, nous avons 2 routes qui ressemblent à /dashboard/:dashboardId et /dashboard/:dashboardId/:maximizedWidgetId

Lorsqu'un utilisateur maximise un widget, nous mettons à jour l'url en utilisant la méthode suivante $location.path mais cela entraîne un nouveau rendu de la vue. Puisque nous avons toutes les données, nous ne voulons pas recharger la vue entière, nous voulons juste mettre à jour l'URL. Existe-t-il un moyen de définir l'URL sans que la vue soit rendue à nouveau ?

HTML5Mode est réglé sur true .

1 votes

Si vous voulez que vos données survivent aux changements de route du côté client, pourquoi ne pas les pousser dans un service ?

133voto

codef0rmer Points 4551

En fait, une vue sera rendue à chaque fois que vous changez une url. C'est ainsi que $routeProvider fonctionne dans Angular mais vous pouvez passer maximizeWidgetId comme une chaîne de requête qui ne rend pas à nouveau une vue.

App.config(function($routeProvider) {
  $routeProvider.when('/dashboard/:dashboardId', {reloadOnSearch: false});
});

Lorsque vous cliquez sur un widget pour l'agrandir :

<a href="#/dashboard/1?maximizeWidgetId=1">Maximum This Widget</a>
or
$location.search('maximizeWidgetId', 1);

L'URL dans la barre d'adresse deviendrait http://app.com/dashboard/1?maximizeWidgetId=1

Vous pouvez même observer quand la recherche change dans l'URL (d'un widget à l'autre).

$scope.$on('$routeUpdate', function(scope, next, current) {
   // Minimize the current widget and maximize the new one
});

1 votes

Si la réponse est acceptée, je créerai une question séparée sans aucun ":param". Question tout à fait stupide : comment ne pas rendre la vue à nouveau.

2 votes

Je pense angular-ui-router sera un choix évident dans ce cas.

1 votes

J'utilise le $routeUpdate événement. Je pense que le $routeChangeStart se déclenche lors du passage à un autre endroit.

9voto

davidb583 Points 833

Vous pouvez donner la valeur false à la propriété reloadOnSearch de $routeProvider.

Possibilité de dupliquer la question : Peut-on modifier un chemin sans recharger le contrôleur dans AngularJS ?

Salutations

0 votes

On dirait que c'est un doublon. Malheureusement, il semble qu'ils aient le même problème, tant que cela fait partie du chemin d'accès à l'URL, et non d'une variable de requête, il se rafraîchit.

0 votes

Non, ce n'est pas un doublon.

0 votes

Il ne s'agit pas d'un doublon, puisque la question liée concerne le non-rechargement du contrôleur et que celle-ci concerne le non-rechargement du modèle. La solution proposée dans la question liée entraînera le rechargement de la vue.

3voto

DreamSonic Points 1147

Nous utilisons Angular UI Routeur au lieu des routes intégrées pour un scénario similaire. Il ne semble pas nécessaire de réinstaurer le contrôleur et de rendre à nouveau la vue entière.

2 votes

Avez-vous essayé d'utiliser $state.transitionTo() au lieu de $location.path() ?

1 votes

Je ne change pas du tout $location.path(), où il faut écrire $state.transitionTo() alors ?

0 votes

Citation : "Lorsqu'un utilisateur maximise un widget, nous mettons à jour l'url en utilisant location.path, mais cela entraîne un nouveau rendu de la vue." Au lieu de modifier le chemin, vous devriez appeler $state.transitionTo() qui à son tour mettra à jour le hash de l'url.

3voto

mr-maw Points 21

Je me rends compte qu'il s'agit d'une vieille question, mais comme il m'a fallu un jour et demi pour trouver la réponse, la voici.

Vous n'avez pas besoin de convertir votre chemin d'accès en chaînes de requête. si vous utilisez angular-ui-router .

Actuellement, en raison de ce que peut être considéré comme un bogue , réglage reloadOnSearch: false sur un état aura pour conséquence de pouvoir modifier l'itinéraire sans recharger la vue. L'utilisateur GitHub lmessinger a même eu la gentillesse de fournir une démo de cette application. Vous pouvez trouver le lien dans son commentaire ci-dessus.

En gros, tout ce que vous devez faire, c'est :

  1. Utilisez ui-router au lieu de ngRoute
  2. Dans vos états, déclarez ceux que vous souhaitez avec reloadOnSearch: false

Dans mon application, j'ai une vue de la liste des catégories, à partir de laquelle vous pouvez accéder à une autre catégorie en utilisant un état comme celui-ci :

$stateProvider.state('articles.list', {
  url: '{categorySlug}',
    templateUrl: 'partials/article-list.html',
    controller: 'ArticleListCtrl',
    reloadOnSearch: false
  });

C'est tout. J'espère que cela vous aidera !

2voto

OZ_ Points 7398

Comment je l'ai mis en œuvre :
(ma solution s'applique principalement aux cas où vous devez modifier l'ensemble de la route, et non des sous-parties).

J'ai une page avec un menu (menuPage) et les données ne doivent pas être nettoyées lors de la navigation (il y a beaucoup d'entrées sur chaque page et l'utilisateur sera très très malheureux si les données disparaissent accidentellement).

  1. désactiver $routeProvider

  2. dans le contrôleur mainPage, ajoutez deux divs avec un attribut de directive personnalisé - chaque directive ne contient que 'templateUrl' et 'scope : true'.

     <div ng-show="tab=='tab_name'" data-tab_name-page></div>
  3. Le contrôleur mainPage contient des lignes pour simuler le routage :

    if (!$scope.tab && $location.path()) {
        $scope.tab = $location.path().substr(1);
    }
    $scope.setTab = function(tab) {
        $scope.tab = tab;
        $location.path('/'+tab);
    };

C'est tout. C'est un peu laid d'avoir une directive séparée pour chaque page, mais l'utilisation de templateUrl dynamique (en tant que fonction) dans la directive provoque un nouveau rendu de la page (et la perte des données des entrées).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X