我已经获得了参数A支持值的已知列表。我需要在触发任何状态结果之前验证状态参数的值,如果该值无效,提供支持的价值。我最初的想法是为参数的value属性使用可注入函数:
params: {
A: {
value: [
'$stateParams',
'validator',
function validateParamA($stateParams, validator) {
// return some value
}
}
}
}
但是,$stateParams
此时未填充(我希望预览版本与解析中的内容类似),并且这可能会设置默认值,而不是{{1本身。所以我正在寻找类似$stateParam
' urlRouterProvider.when
的内容。
我的下一个想法就是使用$match
。没有骰子:令我沮丧的是,在状态解决之后,这会引发。
我的下一个想法是劫持urlMatcherFactory的编码。同样的交易(火灾之后)。
唉!问题是控制器正在通过urlRouterProvider.when
在UI路由器外部执行。将其移到内部应该修复序列问题(然后ngController
应该工作)。将在今天晚些时候更新。
答案 0 :(得分:4)
MarcherFactory做了这个伎俩。在我纠正了ngController废话并将这些控制器带到UI路由器之后,它就像我预期的那样工作。
// url: '/{locale:locale}'
function validateLocale(validator, CONSTANTS, value) {
var match = validator(value);
if (match === true) {
return value;
}
if (match) { // partial match
newLocale = match;
} else {
newLocale = CONSTANTS.defaultLocale;
}
return newLocale;
}
$urlMatcherFactoryProvider.type(
'locale',
{
pattern: ROUTING.localeRegex
},
[
// …
function localeFactory(validator, CONSTANTS) {
return {
encode: validateLocale.bind({}, validator, CONSTANTS)
};
}
]
);
:愤怒:
答案 1 :(得分:2)
我最近遇到了同样的问题,并通过解析回调中的sed
调用解决了这个问题。我有一些日历视图的默认参数,并希望事先验证参数。没有在这个主题上找到任何其他内容,但它似乎是一个非常可靠的解决方案。这是我的样本状态:
$q.defer()
如内联评论中所述,您可以将简单字符串或整个对象传递到$stateProvider.state(
'tasks.list',
{
url : '/:type?month&year&dueDate', // optional params for filtering
params : {
type : {
value : 'all' // all|open|assigned|my
},
month : {
value : 1, // current month, needs a callback, no static value
type : 'int'
},
year : {
value : 2016, // current year, needs a callback, no static value
type : 'int'
},
dueDate : {
value : undefined, // 'no default value' - parses 2016-04-23 to da js date object
type : 'date'
}
},
resolve : {
validParams : ['$q', '$stateParams',
function($q, $stateParams) {
var deferred = $q.defer();
var allowedTypes = ['all', 'open', 'assigned', 'my'];
if (allowedTypes.indexOf($stateParams.type.trim().toLowerCase()) < 0) {
// deferred.reject(reason) also takes a simple string or nothing, you can use this information on UI.Router's $stateChangeError Event
deferred.reject({
error : 'Invalid Value',
param : 'type',
value : $stateParams.type
});
}
if ($stateParams.month < 1 || $stateParams.month > 12) {
deferred.reject({
error : 'Invalid Value',
param : 'month',
value : $stateParams.month
});
}
if ($stateParams.year < 2014 || $stateParams.year > 2099) {
deferred.reject({
error : 'Invalid Value',
param : 'year',
value : $stateParams.month
});
}
// if a _deferred object was already rejected, it can't be resolved anymore, so this doesn't hurt at all
deferred.resolve('Valid Values');
return _deferred.promise;
}],
taskListModel : ['TaskHttpService', '$stateParams',
function(TaskHttpService, $stateParams) {
// no matter if 'validParams' is resolved or not, this is called - so you might want to validate again or do some other check if you make an ajax call
return TaskHttpService.loadTasks({
month : $stateParams.month,
year : $stateParams.year,
dueDate : $stateParams.dueDate
});
}]
},
views : {
menu : {
templateUrl : '/menu.html',
controller : 'MenuController'
},
body : {
templateUrl : '/body.html',
controller : 'BodyController'
}
}
}
)
https://docs.angularjs.org/api/ng/service/ $ q - 您可能希望收听deferred.reject(reason)
上的$stateChangeError
对信息做任何事情:
$rootScope
更新 完成答案后,我发现您在之前要求验证已调用已解析的参数。在标题中你说“在州解决之前” - 所以如果拒绝承诺,国家就不会得到解决。也许这可以帮助你了
答案 2 :(得分:1)
如果在状态结算中解析A并且其他结果依赖于它,您将能够检查$ stateParams并在需要时提供替代值。其他决议将在A。
之后解决$stateProvider
.state('state', {
resolve: {
A: ['$stateParams', 'validator', function($stateParams, validator) {
return validator.validate($stateParams.A) ? $stateParams.A : 'default';
}],
otherResolve: ['A', function(A) {
///
}
}
});
其他结果不应该直接使用$ stateParams,我不知道你是否有问题。
答案 3 :(得分:0)
如何将状态分成两部分:一部分进行验证,另一部分是实际的目标状态。
$stateProvider
.state('validationState', {
// The controller below will not get instantiated without defining template
template: '',
controller: function ($stateParams, $state) {
if (/* your validation */) {
$state.go('targetState', /* simply forward the valid parameter */);
} else {
$state.go('targetState', /* provide your valid parameter value */);
}
}
})
.state('targetState', {
// whatever you want to resolve, yadda yadda
});
不确定控制器是否可以在验证状态定义中用onEnter
替换,但可能。