web-dev-qa-db-fra.com

Mise à jour de l'URL dans Angular JS sans nouvelle visualisation du rendu

Je construis un système de tableau de bord dans AngularJS et je rencontre un problème avec la définition de l'URL via $location.path

Dans notre tableau de bord, nous avons un tas de widgets. Chacune affiche une vue agrandie plus grande lorsque vous cliquez dessus. Nous essayons de mettre en place une liaison en profondeur pour permettre aux utilisateurs de se connecter à un tableau de bord avec un widget maximisé.

Actuellement, nous avons 2 itinéraires qui ressemblent à /dashboard/:dashboardId et /dashboard/:dashboardId/:maximizedWidgetId

Lorsqu'un utilisateur maximise un widget, nous mettons à jour l'URL à l'aide de $location.path, mais la vue est restituée. Puisque nous avons toutes les données, nous ne voulons pas recharger la vue entière, nous voulons simplement mettre à jour l'URL. Existe-t-il un moyen de définir l'URL sans provoquer le rendu de la vue?

HTML5Mode est réglé sur true.

79
Ian Muir

En fait, une vue sera rendue chaque fois que vous modifiez une URL. C’est comme ça que $ routeProvider fonctionne dans Angular mais vous pouvez passer maximizeWidgetId comme une chaîne de requête qui ne rend pas de nouveau le rendu d’une vue.

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

Lorsque vous cliquez sur un widget pour maximiser:

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

L'URL dans addressbar changerait à http://app.com/dashboard/1?maximizeWidgetId=1

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

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

Vous pouvez définir la propriété reloadOnSearch de $ routeProvider sur false.

Question possible en double: Pouvez-vous changer un chemin sans recharger le contrôleur dans AngularJS?

Cordialement

9
bdavidxyz

Pour ceux qui ont besoin de changer de chemin complet () sans recharger les contrôleurs

Voici le plugin: https://github.com/anglibs/angular-location-update

Usage:

$location.update_path('/notes/1');
6
Daniel Garmoshka

Nous utilisons Angular UI Routeur au lieu des routes intégrées pour un scénario similaire. Il ne semble pas ré-instancier le contrôleur ni rendre à nouveau le rendu. vue entière.

3
DreamSonic

Je me rends compte que c’est une vieille question, mais comme il m’a fallu une bonne journée et demie pour trouver la réponse, voilà.

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

Actuellement, à cause de quoi peut être considéré comme un bogue , mettre reloadOnSearch: false sur un état, il sera possible de changer de route sans recharger la vue. L'utilisateur de GitHub, lmessinger, a même eu la gentillesse d'en fournir une démonstration. Vous pouvez trouver le lien de son commentaire lié ci-dessus.

Fondamentalement, tout ce que vous devez faire est:

  1. Utilisation 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 liste de 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 ça. J'espère que cela t'aides!

3
ohanhi

Comment je l'ai implémenté:
(ma solution principalement pour les cas où vous devez changer tout l'itinéraire, pas les sous-parties)

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

  1. désactiver $ routeProvider
  2. dans le contrôleur mainPage, ajoutez deux divs avec l'attribut de directive personnalisée - chaque directive contient uniquement '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. Un peu moche d'avoir une directive distincte pour chaque page, mais l'utilisation de templateUrl dynamique (en tant que fonction) dans la directive provoque un nouveau rendu de la page (et une perte de données d'entrées).

2
OZ_

J'ai une idée à utiliser

window.history.replaceState ('Object', 'Title', '/ new-url');

Si vous faites cela et qu'un cycle de digestion se produit, il va complètement bouleverser les choses. Cependant, si vous redéfinissez l’URL correcte que angular attend, c’est acceptable. Donc, en théorie, vous pouvez stocker l’URL correcte angular attend et réinitialisez-la simplement. avant de connaître un feu de digestion.

Je n'ai pas testé cela cependant.

0
Keegan's hairstyle 82

Si j'ai bien compris votre question, vous voulez,

  1. Maximisez le widget lorsque l'utilisateur est sur/dashboard /: dashboardId et qu'il maximise le widget.
  2. Vous voulez que l'utilisateur ait la possibilité de revenir à/dashboard /: dashboardId /: maximizedWidgetId et de toujours voir le widget agrandi.

Vous pouvez configurer uniquement le premier itinéraire dans routerConfig et utiliser RouteParams pour déterminer si le widget agrandi est transmis dans les paramètres du contrôleur de cet itinéraire configuré et maximiser celui qui a été transmis en tant que paramètre. Si l'utilisateur la maximise pour la première fois, partagez l'URL de cette vue agrandie avec l'ID maximWidgetWidget sur l'interface utilisateur.

Tant que vous utilisez $ location (qui est simplement un wrapper sur un objet location natif) pour mettre à jour le chemin, la vue sera actualisée.

0
Sivakumar Kailasam