AngularJS 1.x中ui-router 1.0.11配合$urlRouterProvider.otherwise参数路由失效求助
解决ui-router 1.0.11中otherwise重定向与带参数路由冲突的问题
我来帮你搞定这个头疼的路由问题~ 核心原因是你的det状态URL配置有问题,导致带参数的路由路径没有匹配到对应的状态,被$urlRouterProvider.otherwise给拦截重定向了。
问题分析
你当前的det状态是作为根状态定义的,但它的URL是"details/:pId/details"(没有以/开头),这会让ui-router对路径的解析出现混乱:
- 如果没有指定父状态,根状态的URL必须以
/开头,否则无法正确匹配独立的路径 - 你希望产品详情页是基于
/products的子页面,但当前配置下det状态和home状态是平级的,点击产品链接生成的路径要么是无效的相对路径,要么是根路径/details/:pId/details(如果手动加/),但如果是后者,你需要确保这个路径确实对应det状态,不过更合理的做法是把它设为home的子状态。
解决方案:将det设为home的子状态
有两种方式可以实现,选其中一种就行:
方式1:通过状态命名嵌套
把det状态命名为home.det,URL使用相对路径(以/开头,相对于父状态的URL):
var app = angular.module("productsApp", [ "ui.router" ]); app.config([ "$stateProvider", "$urlRouterProvider", "$locationProvider", function($stateProvider, $urlRouterProvider, $locationProvider) { $urlRouterProvider.otherwise('/products'); $stateProvider .state("home", { url: "/products", templateUrl: "/products.html", controller: "MainCtrl", resolve: { getAllP: function($http) { return $http.get("/products/get").then(function(res) { return res.data; }); } } }) // 作为home的子状态,命名为home.det .state("home.det", { // 相对父状态的URL,最终完整路径是 /products/details/:pId/details url: "/details/:pId/details", templateUrl: "p_details.html", controller: "productDetailCTRL", resolve: { prDet: function($http, $stateParams) { return $http .get("/products/id/" + $stateParams.pId + "/details") .then(function(res) { return res.data; }); } } }); $locationProvider.html5Mode(true); $locationProvider.hashPrefix("!"); } ]);
方式2:通过parent属性指定父状态
如果不想修改状态名称,可以直接给det状态添加parent: "home"属性:
.state("det", { parent: "home", // 指定父状态为home url: "/details/:pId/details", templateUrl: "p_details.html", controller: "productDetailCTRL", resolve: { prDet: function($http, $stateParams) { return $http .get("/products/id/" + $stateParams.pId + "/details") .then(function(res) { return res.data; }); } } });
页面链接调整
在产品页面(products.html)中,使用子状态的名称来生成链接:
<!-- 如果是方式1,用home.det --> <a ui-sref="home.det({pId: product.id})">{{product.name}}</a> <!-- 如果是方式2,直接用det --> <a ui-sref="det({pId: product.id})">{{product.name}}</a>
为什么之前新增error状态也不行?
因为当时det状态的路径依然没有正确匹配到对应的状态,不管你设置otherwise到/products还是error页面,无效的路径都会被重定向。现在把det设为子状态后,生成的路径/products/details/:pId/details会准确匹配到home.det状态,就不会触发otherwise规则了。
这样修改后,既可以保证未定义的路由(比如/url/abcdef)被重定向到/products,又能让产品详情的带参数路由正常工作~
内容的提问来源于stack exchange,提问作者dani
相关产品推荐
相关产品推荐

