Нечувствительность к регистру с angularjs ui-router

Я создаю новое приложение angularJS на основе шаблона Visual Studio AngularJS SPA (http://visualstudiogallery.msdn.microsoft.com/5af151b2-9ed2-4809-bfe8-27566bfe7d83)

это использует ui-router (https://github.com/angular-ui/ui-router) для своего маршрутизация.

однако, похоже, регистр чувствителен.

Любая идея, как я могу указать angular/ui-router игнорировать случай параметра url?

чувствительность к регистру не имеет значения в приложении, хотя, если пользователь вводит URL-адрес для входа в приложение на определенной странице, нам нужно убедиться, что about также совпадает с aBouT

Ваше здоровье


person Darren Wainwright    schedule 18.02.2014    source источник
comment
Проверьте это: github.com/angular-ui/ui-router/wiki/   -  person Sergiu Paraschiv    schedule 18.02.2014
comment
Думаю, вы могли бы опубликовать это как ответ Серджиу   -  person shaunhusain    schedule 19.02.2014
comment
Я думаю, что ответ здесь лучше всего описывает решение: stackoverflow.com /questions/14994324/ Однако это не четкий дубликат.   -  person Sergiu Paraschiv    schedule 19.02.2014
comment
Большое спасибо, ребята. новый с угловым, поэтому явно пропустил это :)   -  person Darren Wainwright    schedule 19.02.2014


Ответы (4)


Теперь вы можете напрямую настроить ui-router на нечувствительность к регистру. Вот как вы можете его использовать:

angular.module('main', ['ui.router']);

angular.module('main').config(['$urlMatcherFactoryProvider', '$stateProvider', '$urlRouterProvider',
  function($urlMatcherFactory, $stateProvider, $urlRouter) {
    $urlMatcherFactory.caseInsensitive(true);
    $urlMatcherFactory.strictMode(false);
    $stateProvider.state('foo', {
      url: '/foo',
      template: '<b>The Foo View</b>'
    });
    $stateProvider.state('bar', {
      url: '/bar',
      template: '<b>The Bar View</b>'
    });
    $stateProvider.state('nomatch', {
      url: '/nomatch',
      template: '<b>No match found View</b>'
    });

    $urlRouter.otherwise('/nomatch');
  }
]);

В последней версии (0.2.11) это не работает. Исправление уже выпущено, его можно увидеть на Github. Итак, в настоящее время лучшим решением является клонирование ui-router и сборка головы мастера вручную. Кроме того, вы можете просто изменить исходный код вручную, пока не появится следующий выпуск.

ОБНОВЛЕНИЕ (18.11.2014):

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

person kmkemp    schedule 10.11.2014
comment
Я нахожу этот подход намного лучше, чем утвержденный ответ, поскольку он не переписывает URL-адрес. - person sebas2day; 12.12.2014

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

Перед моими маршрутами $stateProvider.state(......) теперь у меня есть этот фрагмент кода:

$urlRouterProvider.rule(function ($injector, $location) {
       //what this function returns will be set as the $location.url
        var path = $location.path(), normalized = path.toLowerCase();
        if (path != normalized) {
            //instead of returning a new url string, I'll just change the $location.path directly so I don't have to worry about constructing a new url string and so a new state change is not triggered
            $location.replace().path(normalized);
        }
        // because we've returned nothing, no state change occurs
    });

По сути, это будет toLowerCase() URL-адрес, который уже не весь в нижнем регистре.

После этого он заменяет URL-адрес, а не перенаправляет. Затем продолжается сопоставление состояния.

person Darren Wainwright    schedule 19.09.2014
comment
Начиная с версии 0.2.12 и выше, это можно сделать одной строкой, не переписывая URL-адреса. Смотрите ответ @kmkemp. - person Matt DeKrey; 02.04.2015
comment
В возрасте с @MattDeKrey это приведет к двойному срабатыванию $stateChangeSuccess из-за перезаписи URL-адреса. Просто введите $urlMatcherFactory.caseInsensitive(true); в функции run() - person Axel; 01.10.2015
comment
@Axel - StateChangeSuccess не сработает дважды. Он срабатывает только один раз. Также упоминает об этом в комментарии в коде - person Darren Wainwright; 01.10.2015
comment
@Darren, это случилось со мной только сегодня, с приведенным выше кодом, использование go(state) дважды срабатывало stateChangeSuccess один с toParam в нижнем регистре и один с toParam в верхнем регистре.... Комментируя строку $location.replace().path(normalized ); остановил это поведение... - person Axel; 01.10.2015

Вы не должны изменять то, как ui-route обрабатывает сопоставление URL-адресов, чтобы принимать URL-адреса, нечувствительные к регистру (это может привести к непредвиденным проблемам), но вы можете попытаться автоматически исправить URL-адреса для пользователя, когда маршруты не работают.

Когда ui-route не может сопоставить URL-адрес с маршрутом, он запускает обратный вызов otherWise(). Я покажу, что вам нужно перенаправить с помощью этого обратного вызова.

Далее предполагается, что все URL-адреса вашего приложения должны быть в нижнем регистре.

var stateHandler = function($urlRouterProvider)
{
    $urlRouterProvider.otherwise(function($injector, $location)
    {
        var url = $location.absUrl();
        var redirect = url.toLowerCase();
        if(url == redirect)
        {
             return;
        }
        $window.location = redirect;
    });
};

YourAngularApp.config(['$urlRouterProvider',stateHandler]);

Если вам нужно больше контроля, используйте регулярное выражение, чтобы выбрать, какие URL-адреса нужно переписать.

person Reactgular    schedule 19.09.2014
comment
Я не уверен, чем это действительно отличается от метода, который я в итоге использовал (по ссылке в комментариях к вопросу - $urlRouterProvider.rule() - кроме правила, будут применены любые изменения, прежде чем пытаться найти маршрут. Где ваше решение сначала проверяет все известные маршруты, затем изменение URL-адреса и затем перенаправление. - person Darren Wainwright; 19.09.2014
comment
И, кстати, вы бы хотели использовать $window против window, чтобы все это оставалось «внутри» angualr. - person Darren Wainwright; 19.09.2014
comment
@Darren Да, я увидел ссылку в комментарии только после того, как опубликовал. Я бы пошел с rule() - person Reactgular; 19.09.2014
comment
а, хорошо :) Я подумал, что должен ответить здесь, чтобы помочь другим :) - я сделаю это сейчас... - person Darren Wainwright; 19.09.2014

Согласно официальной вики,

https://github.com/angular-ui/ui-router/wiki/URL-маршрутизация

Ответ Даррена выглядит правильно:

app.config(function ($urlRouterProvider) {
  // Here's an example of how you might allow case insensitive urls
   $urlRouterProvider.rule(function ($injector, $location) {
   //what this function returns will be set as the $location.url
    var path = $location.path(), normalized = path.toLowerCase();
    if (path != normalized) {
        //instead of returning a new url string, I'll just change the $location.path directly so I don't have to worry about constructing a new url string and so a new state change is not triggered
        $location.replace().path(normalized);
    }
    // because we've returned nothing, no state change occurs
});}
person ApiFox    schedule 16.11.2014