2016-02-12 57 views
0

我有一個角度的應用程序,它由一個index.html頁面和一些局部視圖組成。假設有4個部分視圖:view1,view2,view3和view4。我希望View1成爲當您第一次打開我的主頁/根頁面時加載到index.html中的基本視圖。我通過將我的$urlRouterProvider.otherwise()設置爲我的view1部分來實現。Angular ngRoute/UI-Router奇怪的重定向行爲

出於某種原因,此問題僅出現在特定視圖中。假設它是view3。當我點擊view3上的按鈕時,它應該路由到另一個視圖,比如view4。它總是第一次成功路線。但是,無論何時我通過任何方法返回到view3並嘗試在第一次之後的任何時候路由到view4,它總是強制路由回到$urlRouterProvider.otherwise()中的任何視圖:在這種情況下,它是view1。這不僅僅是視圖4。無論我試圖從view3路由到什麼視圖都無關緊要,它將在第1次成功加載該視圖,然後在總是默認爲$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()方法,並強制將我重定向到我在那裏定義的任何視圖。我不確定此時該做什麼。任何人都可以幫我弄清楚爲什麼我得到這個奇怪的路由行爲?

+0

您在視圖3的控制器中缺少一個關閉paren。 –

+0

謝謝,爲了簡潔起見,當我縮短我的代碼時,我一定會意外地將它遺漏了。我可以向你保證它確實在我的源代碼中關閉了,這不是造成這個問題的原因。 – bscott

+0

您是否在控制檯中看到任何JS錯誤? – SteamDev

回答

0

在挖掘了stackoverflow和github後,我發現問題與ngRoute/Ui路由器服務本身無關。問題在於我在項目中使用的<uib-tabset><uib-accordion>指令模板。它們是Angular Ui-Bootstrap庫的一部分。這是一個已知的問題,已經在角度Ui-bootstrap的github上提出了幾次:如here

如果我對它的理解正確,實際上發生的是這些<uib-tabset><uib-accordion>得到<a>錨標籤追加到他們。這意味着,如果在tabset或accordion(基本上,除純文本以外的任何內容)中都有可點擊的元素,則angular永遠不會收到其點擊事件。它們被瀏覽器攔截,導致奇怪的重定向行爲發生。這就解釋了爲什麼我只是在具有特定視圖的陌生路由行爲而不是我的應用中的所有視圖。

由Angular Ui-Bootstrap團隊here提出的當前修復(向下滾動幾個滴答聲,查看'已知問題'標題的屏幕右下角並閱讀該部分)是修改標記集和手風琴指令模板本身,更改他們將<a>錨標記插入<div>標記的位置。這樣做會導致您失去大多數關聯的CSS樣式,因爲它們基於<a>元素。從這裏開始,只需轉到bootstrap.css,找到所有影響uib-tab和uib-accordion的CSS規則,並更新它們,以便指向div而不是a。