Obecnie nasz projekt używa default $routeProvider
, a ja używam tego "hacka", aby zmienić url
bez przeładowywania strony:
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;
}]);
i w controller
$locationEx.skipReload().path("/category/" + $scope.model.id).replace();
Myślę o wymianie routeProvider
z ui-router
do gniazdowania tras, ale nie mogę znaleźć to w ui-router
.
Czy to możliwe - zrób to samo z angular-ui-router
?
Po co mi to? Pozwól, że wyjaśnię na przykładzie:
Trasa do tworzenia nowej kategorii jest /category/new
po clicking
SAVE Pokazuję success-alert
i chcę zmienić trasę /category/new
na /caterogy/23
(23 - to identyfikator nowego elementu przechowywanego w db)
angularjs
angular-ui-router
vuliad
źródło
źródło
$urlRouterProvider.otherwise
wydaje się, że działa na adresie URL, a nie na stanie. Hmmm, może mógłbym żyć z dwoma adresami URL lub znaleźć inny sposób wskazania, że jest to nieprawidłowy adres URL.Odpowiedzi:
Po prostu możesz użyć
$state.transitionTo
zamiast$state.go
.$state.go
wywołuje$state.transitionTo
wewnętrznie, ale automatycznie ustawia opcje na{ location: true, inherit: true, relative: $state.$current, notify: true }
. Możesz zadzwonić$state.transitionTo
i ustawićnotify: false
. Na przykład:$state.go('.detail', {id: newId})
można zastąpić
$state.transitionTo('.detail', {id: newId}, { location: true, inherit: true, relative: $state.$current, notify: false })
Edycja: zgodnie z sugestią fracza może to być po prostu:
$state.go('.detail', {id: newId}, {notify: false})
źródło
$state.transitionTo('.detail', {id: newId}, { location: true, inherit: true, relative: $state.$current, notify: false })
elementami : więc w zasadzie ustaw powiadomienie na fałsz i lokalizację na prawda$state.go('.detail', {id: newId}, {notify: false})
.OK, rozwiązane :) Angular UI Router ma tę nową metodę, $ urlRouterProvider.deferIntercept () https://github.com/angular-ui/ui-router/issues/64
w zasadzie sprowadza się do tego:
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(); }]);
Myślę, że ta metoda jest obecnie dostępna tylko w wersji głównej routera kątowego ui, tej z opcjonalnymi parametrami (które też są fajne, przy okazji). Musi zostać sklonowany i zbudowany ze źródła z
Dokumenty są również dostępne ze źródła za pośrednictwem
(są wbudowane w katalog / site) // więcej informacji w README.MD
Wydaje się, że jest na to inny sposób, poprzez parametry dynamiczne (których nie używałem). Wiele kredytów dla nateabele.
Na marginesie, oto opcjonalne parametry w $ stateProvider Angular UI Routera, których użyłem w połączeniu z powyższym:
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' }); }]);
co to robi, to pozwala rozwiązać stan, nawet jeśli brakuje jednego z parametrów. SEO to jeden cel, czytelność inny.
W powyższym przykładzie chciałem, aby parametr doorSingle był wymaganym parametrem. Nie jest jasne, jak je zdefiniować. Działa jednak dobrze z wieloma opcjonalnymi parametrami, więc nie stanowi to problemu. Dyskusja jest tutaj https://github.com/angular-ui/ui-router/pull/1032#issuecomment-49196090
źródło
Error: Both params and url specicified in state 'state'
. W dokumentach jest napisane, że jest to również nieprawidłowe użycie. Trochę rozczarowujący.Po spędzeniu dużej ilości czasu z tym problemem, oto co mam w pracy
$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 });
źródło
ui-router
tylko, jak można powiedzieć, że inne rozwiązania zostały pracuje$routerProvider
,$routeProvider
i$stateProvider
są zupełnie różne w architekturze ..$onInit()
mój komponent jest wywoływany za każdym razem, gdy używam$state.go
. Nie wydaje mi się to w 100% w porządku.Powołanie
$state.go($state.current, {myParam: newValue}, {notify: false});
nadal ładuje kontroler, co oznacza, że utracisz dane stanu .
Aby tego uniknąć, po prostu zadeklaruj parametr jako dynamiczny:
$stateProvider.state({ name: 'myState', url: '/my_state?myParam', params: { myParam: { dynamic: true, // <---------- } }, ... });
Wtedy nawet nie potrzebujesz
notify
, po prostu dzwonisz$state.go($state.current, {myParam: newValue})
wystarczy. Neato!
Z dokumentacji :
źródło
Ta konfiguracja rozwiązała dla mnie następujące problemy:
.../
do.../123
Konfiguracja stanu
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 } })
Wywołanie stanów (z dowolnego innego kontrolera)
$scope.editTraining = function (training) { $state.go('training.edit', { trainingId: training.id }); }; $scope.newTraining = function () { $state.go('training.new', { }); };
Kontroler szkolenia
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 ... }
źródło
Jeśli potrzebujesz tylko zmienić adres URL, ale nie chcesz zmienić stanu:
Zmień lokalizację za pomocą (dodaj .replace, jeśli chcesz zastąpić w historii):
this.$location.path([Your path]).replace();
Zapobiegaj przekierowaniu do swojego stanu:
$transitions.onBefore({}, function($transition$) { if ($transition$.$to().name === '[state name]') { return false; } });
źródło
zrobiłem to, ale dawno temu w wersji: v0.2.10 UI-routera coś takiego:
$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 })
źródło
Spróbuj czegoś takiego
$state.go($state.$current.name, {... $state.params, 'key': newValue}, {notify: false})
źródło
Myślę, że wcale nie potrzebujesz do tego routera ui. Dokumentacja dostępna dla usługi $ location mówi w pierwszym akapicie: „... zmiany dotyczące $ location są odzwierciedlane na pasku adresu przeglądarki”. W dalszej części artykułu można przeczytać: „Czego to nie robi? Nie powoduje ponownego załadowania całej strony po zmianie adresu URL przeglądarki”.
Mając to na uwadze, dlaczego nie zmienić po prostu $ location.path (ponieważ metoda jest zarówno pobierającym, jak i ustawiającym) na coś podobnego do następującego:
var newPath = IdFromService; $location.path(newPath);
W dokumentacji zauważa, że droga powinna zawsze zaczynać się od ukośnika, ale będzie go dodać jeśli brakuje.
źródło
ui-router
i używam$location.path(URL_PATH)
, strona automatycznie renderuje się ponownie ?!