AngularJS Ui Router-zmiana adresu url bez przeładowywania stanu

Obecnie nasz projekt używa domyślnego $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 zastąpieniu routeProvider przez ui-router dla tras zagnieżdżania, ale nie mogę tego znaleźć w ui-router.

Czy to możliwe - zrób to samo z angular-ui-router?

Po co mi to? Pozwól, że wyjaśnię za pomocą przykładu:
Trasa tworzenia nowej kategorii to /category/new po clicking na SAVE pokazuję success-alert i chcę zmienić trasę /category/new do /caterogy/23 (23-to id nowej pozycji przechowywanej w db)
Author: imsheth, 2014-05-10

8 answers

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 wywołać $state.transitionTo i ustawić notify: false . Na przykład:

$state.go('.detail', {id: newId}) 

Można zastąpić przez

$state.transitionTo('.detail', {id: newId}, {
    location: true,
    inherit: true,
    relative: $state.$current,
    notify: false
})

Edit: zgodnie z sugestią fraz może być po prostu:

$state.go('.detail', {id: newId}, {notify: false}) 
 145
Author: rezCash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-12 14:58:14

Ok, rozwiązany :) Angular Ui router ma nową metodę, $urlRouterProvider.deferIntercept() https://github.com/angular-ui/ui-router/issues/64

W zasadzie sprowadza się to 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 wersjimaster routera angular ui, tego z opcjonalnymi parametrami(które też są ładne, btw). Musi być sklonowany i zbudowany ze źródła za pomocą

grunt build

Dokumenty są dostępne ze źródła jak również poprzez

grunt ngdocs

(są wbudowane w / katalog stron) / / więcej informacji w README.MD

Wydaje się, że istnieje inny sposób, aby to zrobić, za pomocą parametrów dynamicznych (których nie używałem). Wiele kredytów dla nateabele.


Jako Uwaga boczna, oto opcjonalne parametry w routerze $stateProvider Ui Angular, którego 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'
    });

}]);

To, co robi, to pozwala rozwiązać stan, nawet jeśli brakuje jednego z param. SEO jest jednym celem, czytelność innym.

W powyższym przykładzie chciałem, aby drzwi były wymaganym parametrem. Nie jest jasne, jak je zdefiniować. Działa ok z wieloma opcjonalnymi parametrami, więc nie jest to naprawdę problem. Dyskusja jest tutaj https://github.com/angular-ui/ui-router/pull/1032#issuecomment-49196090

 47
Author: wiherek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-08 00:10:11

Po spędzeniu dużo czasu z tym problemem, oto, co mam 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
});
 13
Author: Pankaj Parkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-02 14:31:11

Ta konfiguracja rozwiązała dla mnie następujące problemy:

  • kontroler szkolenia nie jest wywoływany dwa razy podczas aktualizacji adresu url z .../ do .../123
  • kontroler treningowy nie jest wywoływany ponownie podczas przechodzenia do innego stanu

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 (od dowolnego innego kontrolera)

$scope.editTraining = function (training) {
    $state.go('training.edit', { trainingId: training.id });
};

$scope.newTraining = function () {
    $state.go('training.new', { });
};

Kontroler Treningowy

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 ...
}   
 7
Author: martinoss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-28 14:12:23

Jeśli potrzebujesz tylko zmienić adres url, ale zapobiec zmianie stanu:

Zmień lokalizację za pomocą (add .zastąp jeśli chcesz zastąpić w historii):

this.$location.path([Your path]).replace();

Zapobiegaj przekierowaniu do twojego stanu:

$transitions.onBefore({}, function($transition$) {
 if ($transition$.$to().name === '[state name]') {
   return false;
 }
});
 3
Author: egor.xyz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-26 08:51:20

Zrobiłem to, ale dawno temu w wersji: v0.2.10 UI-router jak 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
  })
 2
Author: sheelpriy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-23 09:04:32

Spróbuj czegoś takiego

$state.go($state.$current.name, {... $state.params, 'key': newValue}, {notify: false})
 0
Author: Eyad Farra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 19:12:47

Myślę, że nie potrzebujesz ui-routera w ogóle do tego. Dokumentacja dostępna dla $location service mówi w pierwszym akapicie,"...zmiany w lokalizacji $są widoczne na pasku adresu przeglądarki."Kontynuuje później, by powiedzieć:" czego to nie robi? Nie powoduje przeładowania pełnej strony po zmianie adresu URL przeglądarki."

Więc, mając to na uwadze, dlaczego po prostu nie zmienić $lokalizacji.path (ponieważ metoda jest zarówno getter jak i setter) z czymś takim jak "po": {]}

var newPath = IdFromService;
$location.path(newPath);

Dokumentacja zauważa, że ścieżka powinna zawsze zaczynać się ukośnikiem, ale to ją doda, jeśli jej nie ma.

 -6
Author: Xaniff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-08 03:33:56