Actuellement, notre projet utilise le $routeProvider
par défaut, et j'utilise ce "hack", pour changer url
sans recharger la page:
services.service('$locationEx', ['$location', '$route', '$rootScope', function($location, $route, $rootScope) {
$location.skipReload = function () {
var lastRoute = $route.current;
var un = $rootScope.$on('$locationChangeSuccess', function () {
$route.current = lastRoute;
un();
});
return $location;
};
return $location;
}]);
et dans controller
$locationEx.skipReload().path("/category/" + $scope.model.id).replace();
Je songe à remplacer routeProvider
par ui-router
pour les itinéraires d'emboîtement, mais je ne peux pas le trouver dans ui-router
.
Est-ce possible - faire de même avec angular-ui-router
?
Pourquoi ai-je besoin de cela? Laissez-moi vous expliquer avec un exemple:
La route pour créer une nouvelle catégorie est /category/new
Après clicking
sur SAUVEGARDER, je montre success-alert
et je veux changer la route /category/new
en /caterogy/23
(23 - est l’id du nouvel élément stocké dans la base de données)
Vous pouvez simplement utiliser $state.transitionTo
au lieu de $state.go
. $state.go
appelle $state.transitionTo
en interne mais définit automatiquement les options sur { location: true, inherit: true, relative: $state.$current, notify: true }
. Vous pouvez appeler $state.transitionTo
et définir notify: false
. Par exemple:
$state.go('.detail', {id: newId})
peut être remplacé par
$state.transitionTo('.detail', {id: newId}, {
location: true,
inherit: true,
relative: $state.$current,
notify: false
})
Edit: Comme suggéré par fracz, cela peut simplement être:
$state.go('.detail', {id: newId}, {notify: false})
Ok, résolu:) Angular UI Router utilise cette nouvelle méthode, $ urlRouterProvider.deferIntercept () https://github.com/angular-ui/ui-router/issues/ 64
fondamentalement, cela revient à ceci:
angular.module('myApp', [ui.router])
.config(['$urlRouterProvider', function ($urlRouterProvider) {
$urlRouterProvider.deferIntercept();
}])
// then define the interception
.run(['$rootScope', '$urlRouter', '$location', '$state', function ($rootScope, $urlRouter, $location, $state) {
$rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {
// Prevent $urlRouter's default handler from firing
e.preventDefault();
/**
* provide conditions on when to
* sync change in $location.path() with state reload.
* I use $location and $state as examples, but
* You can do any logic
* before syncing OR stop syncing all together.
*/
if ($state.current.name !== 'main.exampleState' || newUrl === 'http://some.url' || oldUrl !=='https://another.url') {
// your stuff
$urlRouter.sync();
} else {
// don't sync
}
});
// Configures $urlRouter's listener *after* your custom listener
$urlRouter.listen();
}]);
Je pense que cette méthode est actuellement uniquement incluse dans la version master du routeur angular ui, celle avec des paramètres optionnels (qui sont aussi Nice, btw). Il doit être cloné et construit à partir de la source avec
grunt build
Les documents sont également accessibles depuis la source, via
grunt ngdocs
(ils sont intégrés dans le répertoire/site) // plus d'informations dans README.MD
Il semble y avoir un autre moyen de faire cela, avec des paramètres dynamiques (que je n’ai pas utilisés) . Beaucoup de crédits à nateabele.
En résumé, voici paramètres optionnels dans $ stateProvider du routeur d'interface utilisateur angulaire, que j'ai utilisés en combinaison avec ce qui précède:
angular.module('myApp').config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('main.doorsList', {
url: 'doors',
controller: DoorsListCtrl,
resolve: DoorsListCtrl.resolve,
templateUrl: '/modules/doors/doors-list.html'
})
.state('main.doorsSingle', {
url: 'doors/:doorsSingle/:doorsDetail',
params: {
// as of today, it was unclear how to define a required parameter (more below)
doorsSingle: {value: null},
doorsDetail: {value: null}
},
controller: DoorsSingleCtrl,
resolve: DoorsSingleCtrl.resolve,
templateUrl: '/modules/doors/doors-single.html'
});
}]);
cela permet de résoudre un état, même s'il manque l'un des paramètres. Le référencement est un objectif, la lisibilité un autre.
Dans l'exemple ci-dessus, je souhaitais que le paramètre doorsSingle soit un paramètre obligatoire. On ne sait pas comment les définir. Cela fonctionne bien avec plusieurs paramètres facultatifs, donc pas vraiment un problème. La discussion est ici https://github.com/angular-ui/ui-router/pull/1032#issuecomment-49196090
Après avoir passé beaucoup de temps avec cette question, voici ce que je travaille
$state.go('stateName',params,{
// prevent the events onStart and onSuccess from firing
notify:false,
// prevent reload of the current state
reload:false,
// replace the last record when changing the params so you don't hit the back button and get old params
location:'replace',
// inherit the current params on the url
inherit:true
});
Cette configuration a résolu les problèmes suivants pour moi:
.../
à .../123
Configuration de l'état
state('training', {
abstract: true,
url: '/training',
templateUrl: 'partials/training.html',
controller: 'TrainingController'
}).
state('training.edit', {
url: '/:trainingId'
}).
state('training.new', {
url: '/{trainingId}',
// Optional Parameter
params: {
trainingId: null
}
})
Invocation des états (à partir de tout autre contrôleur)
$scope.editTraining = function (training) {
$state.go('training.edit', { trainingId: training.id });
};
$scope.newTraining = function () {
$state.go('training.new', { });
};
Contrôleur de formation
var newTraining;
if (!!!$state.params.trainingId) {
// new
newTraining = // create new training ...
// Update the URL without reloading the controller
$state.go('training.edit',
{
trainingId : newTraining.id
},
{
location: 'replace', // update url and replace
inherit: false,
notify: false
});
} else {
// edit
// load existing training ...
}
Si vous avez seulement besoin de changer d'URL mais d'empêcher le changement d'état:
Changer de lieu avec (ajoutez .replace si vous voulez remplacer dans l'historique):
this.$location.path([Your path]).replace();
Empêcher la redirection vers votre état:
$transitions.onBefore({}, function($transition$) {
if ($transition$.$to().name === '[state name]') {
return false;
}
});
je l'ai fait il y a longtemps dans la version: v0.2.10 du routeur d'interface utilisateur comme quelque chose comme ceci ::
$stateProvider
.state(
'home', {
url: '/home',
views: {
'': {
templateUrl: Url.resolveTemplateUrl('shared/partial/main.html'),
controller: 'mainCtrl'
},
}
})
.state('home.login', {
url: '/login',
templateUrl: Url.resolveTemplateUrl('authentication/partial/login.html'),
controller: 'authenticationCtrl'
})
.state('home.logout', {
url: '/logout/:state',
controller: 'authenticationCtrl'
})
.state('home.reservationChart', {
url: '/reservations/?vw',
views: {
'': {
templateUrl: Url.resolveTemplateUrl('reservationChart/partial/reservationChartContainer.html'),
controller: 'reservationChartCtrl',
reloadOnSearch: false
},
'[email protected]': {
templateUrl: Url.resolveTemplateUrl('voucher/partial/viewVoucherContainer.html'),
controller: 'viewVoucherCtrl',
reloadOnSearch: false
},
'[email protected]': {
templateUrl: Url.resolveTemplateUrl('voucher/partial/voucherContainer.html'),
controller: 'voucherCtrl',
reloadOnSearch: false
}
},
reloadOnSearch: false
})
Essayez quelque chose comme ça
$state.go($state.$current.name, {... $state.params, 'key': newValue}, {notify: false})
Appel
$state.go($state.current, {myParam: newValue}, {notify: false});
rechargera toujours le contrôleur.
Pour l'éviter, vous devez déclarer le paramètre comme dynamique:
$stateProvider.state({
name: 'myState',
url: '/my_state?myParam',
params: {
myParam: {
dynamic: true,
}
},
...
});
Ensuite, vous n'avez même pas besoin de la notify
, il vous suffit d'appeler
$state.go($state.current, {myParam: newValue})
suffit. Neato!
De la documentation :
Lorsque
dynamic
esttrue
, les modifications apportées à la valeur du paramètre n'entraînent pas la saisie/la sortie de l'état. Les résolutions ne seront pas récupérées et les vues ne seront pas rechargées.[...]
Cela peut être utile pour créer une interface utilisateur dans laquelle le composant se met à jour lorsque les valeurs param changent.