角度路线参数约束

Rob*_*nik 2 routing constraints angularjs

我来自Asp.net MVC世界,路线限制非常有用.我目前正在开发一个包含客户端路由的Angular JS SPA.

我还想在我的客户端路由中添加参数约束,如:

$.routeProvider.when("/post/:id/:name?")
Run Code Online (Sandbox Code Playgroud)

在哪里我想限制我的:id参数只有在这些是数字时才有效.

我没有在Angular Docs中找到类似的东西(至少可以说是可怕的).可以吗?也许还有参数默认值?

Mar*_*tin 11

没有内置的方法来设置路由约束,但您可以通过使用resolve功能轻松地完成它.

module.config(function ($routeProvider) {
    $routeProvider.when('/post/:id/:name', {
        controller: 'PostCtrl',
        resolve: {
            id: function ($q, $route) {
                var deferred = $q.defer(),
                    id = parseInt($route.current.params.id, 10);

                if (!isNaN(id)) {
                    deferred.resolve(id);
                } else {
                    deferred.reject('Id is not a number');
                }

                return deferred.promise;
            },
            // This isn't really needed, you can extract the name using 
            // $routeParams.name as you usually would in the controller.
            name: function ($route) {
                return $route.current.params.name;
            }
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

通过这种方式你可以注入idname进入PostCtrl:

module.controller('PostCtrl', function ($scope, $routeParams, id, name) {

});
Run Code Online (Sandbox Code Playgroud)

id在这种情况下将是一个数字.你当然也可以使用$routeParams.id,$routeParams.name但那些总是字符串.

如果传递了除数字之外的其他内容,那么承诺将被拒绝,您需要处理它,通常在"MainCtrl"或"AppCtrl"中进行处理(如果您正在执行SPA).

module.controller('AppCtrl', function ($scope, $log) {
    $scope.$on('$routeChangeError', function (ev, current, previous, rejection) {
        $log.error('Error changing route: ' + rejection);
        // Will print: Error changing route: Id is not a number
    });
});
Run Code Online (Sandbox Code Playgroud)

更新

您可以将resolve与$routeChangeError事件结合使用来验证路由并在出错时重定向.即使它们未在控制器中注入,也始终运行resolve属性.

resolve: {
    validation: function ($q, $route) {
        var deferred = $q.defer(),
            id = parseInt($route.current.params.id, 10);

        if (!isNaN(id)) {
            deferred.resolve();
        } else {
            deferred.reject('VALIDATION FAILED');
        }

        return deferred.promise;
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的家庭控制器中只需添加:

module.controller('AppCtrl', function ($scope, $location) {
    $scope.$on('$routeChangeError', function (ev, current, previous, rejection) {
        if (rejection === 'VALIDATION FAILED') {
            $location.path('/home');
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

这是解决它的一种非常黑客的方式,你可能更好地使用ui-router(我没有尝试过那个).不幸的是,$routeChangeStart如果需要,不可能听取并中止.否则这可能已经解决得更好了.


Rob*_*nik 5

角度路径源更改 - 最透明的约束

AngularJS源代码中有一个pull请求(由我制作),它为路由参数添加了正则表达式约束.它提供这种路由定义很简单:

/:parameter:regularexpression
Run Code Online (Sandbox Code Playgroud)

一个例子是

/profile/:id:[1-9]\\d*/edit
Run Code Online (Sandbox Code Playgroud)

这意味着id必须是一个不以0开头的数字.

其他要求

当然,这些参数还有一些额外的要求:

  1. 参数不能是可选的或贪婪的 - 如果它结束?或者*这个字符将成为正则表达式的一部分(因为它们都是具有各自含义的正则表达式标记)

  2. 正则表达式约束不能使用正则表达式捕获组作为()获得转义为正则表达式约束的一部分-这已经以这种方式工作,所以如果你的参数名称包括()他们都将被转义

  3. 正则表达式约束不能包括,/因为这些是路径段分隔符

  • @BuhBuh是的,我能做什么......没什么.这已经超过一年前提出要求了... (2认同)