Angular ngRoute / UI-Router奇怪的重定向行为

时间:2016-02-12 19:11:58

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

我有一个角度应用程序,它由一个index.html页面组成,里面有一些部分视图。假设有4个部分视图:view1,view2,view3和view4。我希望View1成为第一次点击我的主页/根页面时加载到index.html的基本视图。我这样做是将$urlRouterProvider.otherwise()设置为我的view1 partial。

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

这更令人奇怪的是,即使它强制路由到否则(),我知道我尝试路由到的任何部分的控制器/视图正在加载。如果我将$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);
                    }]);

的index.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()方法并强制将我重定向到我在那里定义的任何视图。我不知道此时该做什么。任何人都可以帮我弄清楚为什么我会遇到这种奇怪的路由行为?

1 个答案:

答案 0 :(得分:0)

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

如果我理解正确的话,基本上发生的事情就是这些<uib-tabset><uib-accordion>获取<a>个锚标记。这意味着,如果你的tabset或accordion中有任何可点击的元素(基本上是纯文本以外的任何东西),angular永远不会收到他们的点击事件。它们被浏览器截获,导致奇怪的重定向行为发生。这就解释了为什么我只有特定视图的奇怪路由行为而不是我应用中的所有视图。

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