web-dev-qa-db-fra.com

Angularjs $ location service apparemment ne pas analyser l'url?

J'utilise angular dans une application qui est, fondamentalement, une table avec des résultats de recherche. L'accès à cette table peut être réalisé via une URL comme http://myapp/?client=clientName

Un contrôleur angular est instancié pour la table, entre autres, pour ouvrir une boîte de dialogue modale (également angulaire avec bootstrap-ui) avec les détails de la ligne.

Ces détails de ligne sont apportés via un service qui a des fonctionnalités communes pour les deux contrôleurs: celui pour la table et celui pour le modal.

Maintenant, dans ce service, j'ai l'extrait de code suivant à récupérer:

service.fetchRelatedElements = function(element, cb) {
  var url = '/search.json?results=20&type='+element.type;
  if ($location.search()['client']) {
    url += '&client=' + $location.search('client');
  }
  return doFetch(url, cb); // actual server json GET
};

Le but est de savoir si la table a déjà ce paramètre client spécifique défini comme filtre.

Si je mets un point d'arrêt au début de cet appel, je vois que $location.absUrl() renvoie l'URL actuelle du navigateur (qui, dans mon cas, a le paramètre client qui m'intéresse).

Mais $location.search() renvoie un objet vide.

J'injecte le service $ location dans mon service avec les valeurs par défaut (c'est-à-dire que je ne le configure pas par un appel .config()). Et, comme le dit doc:

Le service $ location analyse l'URL dans la barre d'adresse du navigateur (en fonction de window.location) et met l'URL à la disposition de votre application.

Suis-je en train de manquer quelque chose? L'URL ne doit-elle pas, à ce stade, être analysée?

Merci!


MISE À JOUR: J'ai réussi à le faire fonctionner. Le problème était exactement que je ne configurais pas du tout le service. Je l'ai fait parce que je supposais que de cette façon, cela prendrait les valeurs par défaut, mais il semble que ce ne soit pas ainsi que cela fonctionne.

31
Pipetus

J'avais le même problème avant de configurer $locationProvider dans la configuration du module de mon application:

appModule.config(['$locationProvider', function($locationProvider) {
        $locationProvider.html5Mode(true);
    }]);
43
Riley Lark

Si vous ne souhaitez pas spécifier la balise de base, vous pouvez spécifier require base false.

myapp.config(function($locationProvider) {
    $locationProvider.html5Mode({
      enabled: true,
      requireBase: false
    });
});
11

Lorsque j'ai rencontré ce problème, une autre chose qui a fonctionné pour moi en plus de définir la configuration est d'ajouter "#" devant la chaîne de requête.

Donc, si vous êtes celui qui crée la chaîne de requête, puis changez
myapp/?client=clientName
à
myapp/#?client=clientName

permis à $ location.search () de me donner un objet non vide auquel vous pourrez ensuite accéder à chaque paramètre en utilisant $location.search()['client']

5
Angel Gao

Vous pouvez écrire une fonction qui analyse la $ window.location.search basée sur ce commentaire https://github.com/angular/angular.js/issues/7239#issuecomment-420475

function parseLocation(location) {
    var pairs = location.substring(1).split("&");
    var obj = {};
    var pair;
    var i;

    for (i in pairs) {
        if (pairs[i] === "")
            continue;

        pair = pairs[i].split("=");
        obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    }

    return obj;
}

$scope.query = parseLocation($window.location.search)['query'];
3
Archimedes Trajano

L'API de $ location.search est assez déroutante. Appel

$location.search('client');

définira l'objet de recherche sur {client: true} et renverra $ location. De plus, vous avez une faute de frappe client au lieu de 'client', il définit donc la recherche sur un objet vide. Vous voulez donc probablement:

url += '&client=' + $location.search()['client'];
3
Jmr