Mon routeProvider pour la route a reloadOnSearch réglé sur false :
$routeProvider
.when(
"/film/list",
{
templateUrl: '/film/list.html',
controller: FilmListController,
reloadOnSearch: false
}
....
)
J'ai fait cela parce que je ne veux pas que le contrôleur entier soit rechargé après les changements de chaîne de requête, mais je l'utilise toujours et l'url ressemble à ceci: film/list?sort=isbn&order=asc&offset=0
. Maintenant, chaque fois que la chaîne de requête change, je veux appeler une fonction depuis mon contrôleur. J'ai donc essayé de configurer une $ watch dans le contrôleur:
$scope.location = $location;
$scope.$watch( 'location.search()', function( search) {
$scope.list();
});
Mais ça ne marche pas. Si je mets $ watch pour surveiller les changements d'un paramètre individuel d'une chaîne de requête, alors cela fonctionne. Mais je ne veux pas définir $ watch pour chaque paramètre de ma chaîne de requête. La solution que j'utilise maintenant est la suivante:
$scope.location = $location;
$scope.$watch( 'location.url()', function( url ) {
if($location.path() == '/film/list')
$scope.list();
});
Donc, au lieu de regarder pour la recherche, je regarde toute l'URL, puis je vérifie si le chemin est celui que j'ai défini dans routeProvider pour appeler conditionnellement le une fonction. Ce que je n'aime pas dans cette solution, c'est que je dois saisir explicitement la valeur de $ location.path à faire correspondre.
Quelqu'un peut-il suggérer une meilleure solution et peut-être m'expliquer pourquoi $ watch ne fonctionne pas pour $ location.search ( ) ?
Vous pouvez écouter $routeUpdate
événement dans votre contrôleur:
$scope.$on('$routeUpdate', function(){
$scope.sort = $location.search().sort;
$scope.order = $location.search().order;
$scope.offset = $location.search().offset;
});
Dans le cas où vous n'utilisez pas la résolution d'itinéraire d'Angular ou si vous voulez simplement savoir à chaque fois que $ location change, il y a un événement juste à cet effet
$rootScope.$on('$locationChangeSuccess', function(event){
var url = $location.url(),
params = $location.search();
})
La réponse des Stewies est correcte, vous devriez écouter les événements $routeUpdate
Pour cela car c'est plus efficace.
Mais pour expliquer pourquoi votre montre ne fonctionne pas; lorsque vous regardez location.search()
, vous regardez si la référence renvoyée par la méthode de recherche est la même ou non. Et il renverra la référence au même objet chaque fois que vous l'appelerez, c'est pourquoi votre montre ne se déclenche pas. Autrement dit, même si les paramètres de recherche changent, c'est toujours le même objet qui est renvoyé. Pour contourner cela, vous pouvez passer true comme troisième argument à $watch
. Cela indiquera Angular à comparer par valeur, pas par référence. Mais soyez prudent lorsque vous créez de telles montres, car elles consommeront plus de mémoire et prendront plus de temps à s'exécuter. C'est pourquoi vous devriez le faire comme dit Stewart.
Utilisation
$scope.$watch(function(){ return $location.search() }, function(params){
console.log(params);
});
au lieu.
$ watch (watchExpression, listener, [objectEquality]);
watchExpression => devrait être soit
Alors ici, vous devez passer votre premier paramètre en tant que fonction.
Exemple JavaScript =>
$scope.$watch (
function () { return $scope.$location.search(); };
function (value) { console.log(value); }
);
exemple TypeScript =>
this.$scope.$watch (
() => { return this.$location.search(); },
(value: any) => { console.log(value); }
) ;
Cela a fonctionné pour moi.
Regardez le changement sur routeUpdate
comme ceci dans le contrôleur:
$scope.$watch('$routeUpdate', function(){
$scope.sort = $location.search().sort;
$scope.order = $location.search().order;
});