Обработка конечных косых черт в маршрутизаторе AngularUI

#angularjs #angular-ui #angular-ui-router #angular-routing

#angularjs #angular-пользовательский интерфейс #angular-ui-router #angular-маршрутизация

Вопрос:

Прошло несколько часов с тех пор, как я начал работать над этой проблемой, и, похоже, я не могу разобраться с решением.

У меня есть приложение, которое может привести к тому, что пользователи действительно будут вводить URL-адрес. В таких случаях нетрудно поверить, что пользователь может ввести завершающую косую черту. Например,

www.example.com/users/2 и www.example.com/edit/company/123

следует рассматривать так же, как

www.example.com/users/2 / и www.example.com/edit/company/123/

Это нужно сделать только для обработки маршрутизации URL на стороне клиента. Я не заинтересован в обработке конечных косых черт в вызовах ресурсов / API. Меня интересует только обработка конечных косых черт в браузере.

Итак, я исследовал и нашел не так много ответов в сети. Большинство из них привели меня к разделу часто задаваемых вопросов angular-ui router.

https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions

Здесь они говорят нам написать правило, что я и хочу сделать, но, похоже, оно не работает, или, может быть, я делаю это неправильно.

Вот plunkr, куда я добавил свой код.

http://plnkr.co/edit/fD9q7L?p=preview

Я добавил это в свою конфигурацию, остальная часть кода — это в значительной степени базовый материал.

 $urlRouterProvider.rule(function($injector, $location) {
  //if last charcter is a slash, return the same url without the slash
  if($location.$url[length-1] === '/') {
    return $location.$url.substr(0,$location.$url.length - 2);
  } else {
    //if the last char is not a trailing slash, do nothing
    return $location.$url;
  }
});
 

По сути, я хочу сделать конечную косую черту необязательной, то есть ее наличие или отсутствие в адресной строке не должно влиять на загруженное состояние.

Ответ №1:

Существует ссылка на рабочий плунжер

И это обновленное определение правила:

   $urlRouterProvider.rule(function($injector, $location) {

    var path = $location.path();
    var hasTrailingSlash = path[path.length-1] === '/';

    if(hasTrailingSlash) {

      //if last charcter is a slash, return the same url without the slash  
      var newPath = path.substr(0, path.length - 1); 
      return newPath; 
    } 

  });
 

И теперь эти ссылки будут работать правильно:

   <ul class="nav">
    <li><a ui-sref="route1">Route 1</a></li>
    <li><a ui-sref="route2">Route 2</a></li>
    <li><a href="#/route1/">#/route1/</a></li>
    <li><a href="#/route2/">#/route2/</a></li>
    <li><a href="#/route1" >#/route1</a></li>
    <li><a href="#/route2" >#/route2</a></li>
  </ul>
 

Волшебство можно определить так: возвращайте измененное значение, если есть изменение … в противном случае ничего не делайте… см. Пример

Комментарии:

1. Упс. Я вызывал неправильный метод в $location . :{ Такая ошибка новичка

2. AFAIK, это будет работать только тогда, когда вы определите это правило в каждом модуле вашего приложения. Это может быть нормально, но в итоге вы получаете дублирующийся код во всех конфигурациях маршрутизатора на стороне клиента; если вы разделили их на каждый модуль. Кто-нибудь решил это на уровне приложения?

3. @MichaelLeanos, это действительно работает, если вы структурируете свои модули таким образом, чтобы был один основной модуль, в который были введены все остальные модули. Взгляните на исходный код Yoda на GitHub. Все, что вам нужно сделать, это добавить вашу общую функциональность в основной конфигурационный файл, и она будет работать во всем вашем приложении Angular.

4. @Cyn ты прав. Я понял это после того, как углубился в проблему, с которой столкнулся. У меня есть модуль с именем «Core», в котором я определял правило . Однако способ загрузки моих модулей был в алфавитном порядке. Я специально тестировал модуль, который стоял перед «Core» в алфавитном порядке, и правило не было применено. Затем я протестировал другой модуль, который появился позже; он работал. Итак, я понял недостаток. В итоге я просто вставил модуль «Core» в каждый из моих других модулей в качестве зависимости. Я полагаю, это то, что вы описываете.

5. Да, похоже, это сработает. Не совсем то, что я имел в виду. На самом деле, моя идея заключалась в том, чтобы внедрить все остальные модули в основной модуль и иметь основной базовый файл, который управляется этим основным модулем, чтобы вы всегда могли отключить приложение, если хотите, не слишком ломая материал. Вот пример:

Ответ №2:

Начиная с версии пользовательского интерфейса 0.2.11, вы можете сделать это:

 $urlMatcherFactoryProvider.strictMode(false);
 

Это будет одинаково обрабатывать URL-адреса с и без конечных косых черт.

Комментарии:

1. Также совместим с версиями 1.x

Ответ №3:

У меня недостаточно репутации для комментария, поэтому я отвечаю :-

 $urlMatcherFactoryProvider.strictMode(false);
 

Должно быть перед $stateProvider.state частью.

Комментарии:

1. !ВАЖНО! Должно быть перед частью $stateProvider.state .!

Ответ №4:

urlMatcherFactoryProvider не рекомендуется для версии v1.x angular-ui-router.

Вместо этого используйте urlService.config.strictMode (ng1, ng2) .

Это все еще должно быть раньше $stateProvider.state() .

 myApp.config(function($stateProvider, $urlServiceProvider) {
  var homeState = {
    name: 'home',
    url: '/home',
    component: 'xyHome'
  };

  $urlServiceProvider.config.strictMode(false);

  $stateProvider.state(homeState);
 

});

Ответ №5:

Привет, вам нужно установить strictMode = false метод предоставления Angular ui-router для этого

 $urlMatcherFactoryProvider.strictMode(false); 
 

Перед инициализацией состояния необходимо установить строгий режим $stateProvider.state({})

Для получения более подробной информации вы можете обратиться по этой ссылке

Ответ №6:

Вы также можете сделать это, используя $urlRouterProvider.otherwise для обработки случаев, когда маршрутизатор не может сопоставить путь.

В следующем примере маршрутизатор не может выполнить сопоставление /mypath и поэтому вызывает $urlRouterProvider.otherwise , чтобы узнать, что делать. Здесь мы можем увидеть запрошенный путь и сопоставить его с правильным путем, т.е. /mypath/

 app.config(function($urlRouterProvider) {
    $urlRouterProvider.otherwise(function ($injector, $location) {
        if ($location.$$path == '/mypath')
            return "/mypath/";
        else
            return "/defaultpath";
    });