【问题标题】:Angular ngRoute/UI-Router strange redirect behaviourAngular ngRoute/UI-Router 奇怪的重定向行为
【发布时间】:2016-05-24 01:35:03
【问题描述】:

我有一个 Angular 应用程序,它由一个 index.html 页面组成,里面有一些部分视图。假设有 4 个局部视图:view1、view2、view3 和 view4。我希望 View1 成为当您第一次访问我的主页/根页面时加载到 index.html 中的基本视图。我通过将我的$urlRouterProvider.otherwise() 设置为我的 view1 部分来做到这一点。

出于某种原因,此问题仅发生在特定视图中。假设它是view3。当我单击 view3 上的按钮时,它应该路由到另一个视图,比如 view4。它总是第一次成功路由。但是,每当我通过任何方法返回 view3 并尝试在第一次之后的任何时间路由到 view4 时,它总是强制路由回到 $urlRouterProvider.otherwise() 中的任何视图:在这种情况下它是 view1。也不仅仅是 view4。无论我尝试从 view3 路由到哪个视图,它都会第一次成功加载该视图,然后在它始终默认为 $urlRouterProvider.otherwise() 视图之后的任何时间。

更奇怪的是,即使它强制路由到 else(),我知道我试图路由到的任何部分的控制器/视图正在加载。如果我将$urlRouterProvider.otherwise() 设置为我的应用程序中不存在的路由,然后重现这种奇怪的行为,结果是 url 显示为 'localhost:8080/routeThatDoesNotExist',但屏幕上实际显示的是什么是我试图路由到的视图。这是我的代码的缩写版本:

app.js:

var app = angular.module('app', ['ui.router', 'controllers','services']);

app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
                    function($stateProvider, $urlRouterProvider, $locationProvider) {
                      $urlRouterProvider.otherwise("/");
                      $stateProvider.
                        state('root', {
                          url: "/",
                          templateUrl: 'partials/view1.html',
                          controller: 'View1Ctrl',
                        }).
                        state('view2', {
                          url: "/view2",
                          controller: 'View2Ctrl',
                          templateUrl: 'partials/view2.html'
                        }).
                        state('view3', {
                          url: "/view3",
                          controller: 'View3Ctrl',
                          templateUrl: 'partials/view3.html',
                        }).
                        state('view4', {
                          url: "/view4",
                          templateUrl: 'partials/view4.html',
                          controller: 'View4Ctrl',
                        });
                        //more views omitted for brevity...
                        $locationProvider.html5Mode(true);
                    }]);

索引.html

<!doctype html>
<html ng-app="app">
<head>
    <base href="/">
    <title>App</title>
    <link rel="...">
    <style>...</style>
</head>

<body>

<div ng-controller="IndexDotHtmlCtrl">
        <button ui-sref="root">View1</button>
        <button ui-sref="view2">View2</button>
        <button ui-sref="view3">View3</button>
        <div ui-view></div>
</div>
<script src="..."></script>
</body>
</html>

View3.html

<div>
    <button ng-click="stateGo()">Go To Another View</button>
</div>

Controllers.js

var controllers = angular.module('controllers', []);

controllers.controller('IndexDotHtmlCtrl', ['$scope', function($scope) {
    //code omitted...
}]);

controllers.controller('View1Ctrl', ['$scope', '$state', function($scope, $state) {
    //code omitted...
}]);

controllers.controller('View2Ctrl', ['$scope', '$state', function($scope, $state) {
    //code omitted...
}]);

controllers.controller('View3Ctrl', ['$scope', '$state', function($scope, $state) {

   $scope.stateGo = function() {
       $state.go('view4');
   }
   //more code omitted...

}]);

controllers.controller('View4Ctrl', ['$scope', '$state', 'SomeSvc', function($scope, $state, SomeSvc) {

    $scope.RESTful_DATA = SomeSvc.query(); //using ngResource
    //more code omitted...

}]);

我尝试做的事情:我最初在使用 Angular 的 ngRoute 时遇到了这个问题,所以我将整个应用程序移至 Angular UI-Router,但问题仍然存在。

认为 $locationProvider 和 html5Mode 可能与它有关。删除了那些在我的网址中添加了 # 的内容。问题仍然存在。

总之,问题在于,每当我尝试专门从 view3 路由到我的应用程序中的任何其他视图时,它总是第一次工作。之后的任何时候,它都会调用$urlRouterProvider.otherwise() 方法并强制将我重定向到我在其中定义的任何视图。我不确定此时该怎么做。谁能帮我弄清楚为什么会出现这种奇怪的路由行为?

【问题讨论】:

  • 您在视图 3 的控制器中缺少一个结束括号。
  • 谢谢,为了简洁起见,我在缩短代码时一定是意外遗漏了它。我可以向你保证,它确实在我的源代码中被关闭了,这不是造成这个问题的原因。
  • 您是否在控制台中看到任何 JS 错误?

标签: angularjs angular-ui-router angular-routing ngroute


【解决方案1】:

在挖掘了 stackoverflow 和 github 之后,我发现这个问题与 ngRoute/Ui-router 服务本身无关。问题在于我在项目中使用的&lt;uib-tabset&gt;&lt;uib-accordion&gt; 指令模板。它们是 Angular Ui-Bootstrap 库的一部分。这是一个已知问题,在 Angular Ui-bootstrap 的 github 上已多次提出:例如 here

如果我理解正确,基本上发生的事情是这些&lt;uib-tabset&gt;&lt;uib-accordion&gt; 获得了附加到它们的&lt;a&gt; 锚标记。这意味着,如果您的标签集或手风琴中有任何可点击的元素(基本上,除了纯文本之外的任何内容),angular 永远不会收到他们的点击事件。它们被浏览器拦截,导致发生奇怪的重定向行为。这解释了为什么我只在特定视图而不是我的应用程序中的所有视图中出现奇怪的路由行为。

Angular Ui-Bootstrap 团队 here 提出的当前修复(向下滚动几个刻度,查看屏幕右下角附近的“已知问题”标题并阅读该部分)是修改tabset 和手风琴指令模板本身,将它们插入&lt;a&gt; 锚标记的位置更改为&lt;div&gt; 标记。这样做会导致您丢失大部分相关的 CSS 样式,因为它们基于 &lt;a&gt; 元素。从这里,只需转到您的 bootstrap.css,找到所有影响 uib-tab 和 uib-accordion 的 CSS 规则,然后更新它们,使它们指向 div 而不是 a。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 2010-12-08
    • 1970-01-01
    相关资源
    最近更新 更多