Я пытался использовать типы параметров с ui-router и не могу понять их правильно.

$stateProvider.state({ name: 'home.foo', url: '/foo/{isBar:bool}', controller: function() { }, templateUrl: 'foo.html' });

Я ожидаю, что я смогу перейти в это состояние следующим образом:

$state.go(home.foo, { isBar: false })

Или

ui-sref="home.foo({ isBar: false })"

Однако в результирующем $stateParams вы увидите isBar: true

Глядя на то, как пишется тип параметра 'bool' Я полагаю, что true/false должно быть закодировано как 0/1 в URL-адресе, но этого не происходит. Если использовать 0/1 в параметрах для $state.go, тогда он работает и декодируется как false/true, но чтобы еще больше запутать проблему, это не работает при использовании ui-sref.

Надеюсь, этот плункер объяснит это лучше. Любые подсказки приветствуются!

Изменить: моя цель использования типа bool param - получить логический тип данных в $stateParams

11
brahnp 27 Ноя 2014 в 23:19
1
Это ошибочное поведение в 0.2.13, и оно было исправлено в этом коммите: github.com /angular-ui/ui-router/commit/…. Если вы строите из мастера, ваш планк работает. plnkr.co/edit/u3NsF0PSmNt3HWiQkdvP?p=preview
 – 
Chris T
29 Дек 2014 в 18:58
Эй, спасибо, Крис! Это также закроет этот вопрос для вас? github.com/angular-ui/ui-router/issues/1655
 – 
brahnp
29 Дек 2014 в 21:35

2 ответа

Существует обновленный и работающий плункер с пользовательским типом boolean.

В случае, если мы хотели бы работать с типом типа bool, который ожидает и принимает:

true, false, 0, 1 >

Нам просто нужно зарегистрировать наш пользовательский тип:

app.config(['$urlMatcherFactoryProvider', function($urlMatcherFactory) {

  $urlMatcherFactory.type('boolean',
    // our type custom type
    {
     name : 'boolean',
     decode: function(val) { return val == true ? true : val == "true" ? true : false },
     encode: function(val) { return val ? 1 : 0; },
     equals: function(a, b) { return this.is(a) && a === b; },
     is: function(val) { return [true,false,0,1].indexOf(val) >= 0 },
     pattern: /bool|true|0|1/
    })

}]);

И затем мы можем использовать это определение URL внутри любого состояния:

...
, url: '/foo/{isBar:boolean}'
...

ПРИМЕЧАНИЕ. Почему boolean? не bool? Поскольку bool уже зарегистрирован для 0|1, насколько я помню

Проверьте это здесь

ОРИГИНАЛ

Простое решение, работающее со "строками" в этом обновленном плункере,

... // states definitions
, url: '/foo/{isBar:(?:bool|true|0|1)}'
11
Radim Köhler 28 Ноя 2014 в 15:08
Однако тип в $stateParam является строкой. Теперь я понимаю, что я не совсем ясно выразился в своем вопросе, но результат, который мне нужен, - { isBar : true/false }
 – 
brahnp
28 Ноя 2014 в 13:51
Сила UI-Router безгранична ;) Наслаждайтесь ;)
 – 
Radim Köhler
28 Ноя 2014 в 15:01
Спасибо, Радим, похоже, это больше, чем я хотел :) Я посмотрел на регистрацию пользовательского типа, но сначала хотел попытаться понять, почему не работает bool по умолчанию. Я до сих пор не совсем понимаю, чего он должен достичь, или он просто сломан!
 – 
brahnp
28 Ноя 2014 в 15:34
К счастью, у вас есть ответ с помощью boolean;) если вы хотите узнать больше, просмотрите исходный код здесь: github.com/angular-ui/ui-router/tree/master/src. Удачи с UI-маршрутизатором ;)
 – 
Radim Köhler
28 Ноя 2014 в 15:35
Спасибо @RadimKöhler. Интересно, может ли он определить, когда строка запроса undefined. Например, /foo?{isBar:boolean} для предоставления false, когда фактический URL-адрес /foo без строки запроса. Я пытаюсь понять это сейчас. Насколько я проверял, undefined не совпадает с $state.includes.
 – 
PSWai
30 Янв 2015 в 06:41

Итак, покопавшись в нескольких файлах, я обнаружил, почему последние два способа (0,1) не работают в ui-sref. В строке 106 stateDirectives.js есть этот вызов: newHref = $state.href(ref.state, params, options);

Это вернет null в случае использования 1 и 0. И поскольку за приведенным выше вызовом следует следующее:

 if (newHref === null) {
      nav = false;
      return false;
    }

Ссылка никогда не делается. Теперь возвращается причина null. state.href вызывает urlRouter.href. Внутри это вызов для проверки параметров. Проверка такова: result = result && (isOptional || !!param.type.is(val));

Когда вы посмотрите на функцию is для bool (is: function(val) { return val === true || val === false; }), вы увидите, почему это не работает, поскольку 1 и 0 не равны true или false. На мой взгляд, он также должен проверять 1 и 0, если это то, во что он в конечном итоге преобразуется, но, по крайней мере, теперь вы знаете, почему он ведет себя именно так.

1
Jason 28 Ноя 2014 в 00:02
Спасибо Джейсон. Я обновил плункер, чтобы включить пример с использованием $state.go, однако это то же поведение, что и ui-sref. В моем более сложном приложении 0/1 правильно декодирует значение false/true. Я буду продолжать пытаться воспроизвести это в плункере.
 – 
brahnp
28 Ноя 2014 в 00:28