You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:35:03