角度路线参数约束

时间:2014-01-18 15:15:13

标签: angularjs routing constraints

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

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

$.routeProvider.when("/post/:id/:name?")

我希望将:id参数限制为只有在这些数字时才有效。

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

3 个答案:

答案 0 :(得分:10)

没有内置的方法来设置路由约束,但是你可以通过使用解析功能轻松地完成它。

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;
            }
        }
    });
});

通过这种方式,您可以将idname注入PostCtrl

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

});
在这种情况下,

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
    });
});

<强>更新

您可以将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;
    }
}

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

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

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

答案 1 :(得分:5)

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

有一个pull request in AngularJS source(由我制作),它为路由参数添加正则表达式约束。它提供这种路由定义很简单:

/:parameter:regularexpression

一个例子是

/profile/:id:[1-9]\\d*/edit

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

附加要求

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

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

  2. 正则表达式约束不能使用正则表达式捕获组作为()作为正则表达式约束的一部分进行转义 - 这已经以这种方式工作,因此如果您的参数名称包含{ {1}}或(他们都将被转义

  3. 正则表达式约束不能包含),因为它们是路径段分隔符

答案 2 :(得分:2)

一种方法是使用ui-router,它允许使用正则表达式指定网址。