2015-08-20 266 views
1

嗯,我有這個項目,和ui路由器給我很難的時間。我做了一個快速Plunker演示:http://plnkr.co/edit/imEErAtOdEfaMMjMXQfD?p=preview角ui路由器奮鬥

所以基本上我有一個主視圖,index.html,成其他頂級的觀點得到注入,這樣operations.index.html。我的大腦中的痛苦開始於頂級視圖中存在多個命名視圖時,operations.detail.htmloperations.list.html被注入operations.index.html,後者又注入index.html

基本上,我想要實現的是以下行爲:

  1. 當用戶點擊導航欄Operations項目,顯示空(新)操作的頁面。網址是/operations
  2. 當他們選擇一個列表中的項目時,這些字段會更新一些數據(數據通過服務請求,但爲了簡單起見,我們假設它在控制器中)。網址是/operations/:id
  3. 如果他們決定,他們希望創建一個新的項目,在編輯當前,他們可以單擊列表頂部New operation按鈕時,URL變化從/operations/:id/operations
  4. 無論新舊項目,導航欄中的項目Operations都保持活動狀態。
  5. 如果用戶正在編輯一個項目,如果他們創建了一個新項目,應該在列表中高亮顯示爲活動狀態 - New operation按鈕應該相應地高亮顯示。

現在,查看奇怪的行爲:轉到Operations,然後再次單擊Operations導航欄項目。一切都消失了。如果我做Operations - >選擇Operation 1 - >選擇New operation也會發生同樣的情況。

另外,請檢查出的部分,我試圖讓id參數:

$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) { 
    if (toParams) { 
    if (toParams.id) { 
     for (var i = 0; i < vm.operations.length; i++) { 
     if (vm.operations[i].id == toParams.id) { 
      vm.operation = vm.operations[i]; 
      break; 
     } 
     } 
    } 
    } 
}); 

我不是專家,但似乎太漫長而複雜的是真實的,尤其是對於這樣一個簡單的任務作爲獲取請求參數。如果我試圖檢查狀態變化$stateParams該對象是空的,因此這種解決方法。如果我試圖篡改app.js中的狀態,情況會稍有變化,但總有一些錯誤,如Operations導航條項失去其活動狀態或其他奇怪的東西。

我知道問這樣的一般性問題在SO中是不常見的,但我實在無法理解ui-router的概念,而且我可以感覺到我在這裏做錯了事,我會很感激幫助指導我如何正確使用ui-router用於我的目的的正確方向。乾杯。

回答

1

the updated plunker

我剛使用的技術從這種問答&答:Redirect a state to default substate with UI-Router in AngularJS

我添加redirectTo設置(可以是在任何狀態)

.state('operations', { 
     url: '/operations', 
     templateUrl: 'operations.index.html', 
     controller: 'operationsController as op', 
     // here is redirect 
     redirectTo: 'operations.new', 
}) 

和加了這個redirector

app.run(['$rootScope', '$state', function($rootScope, $state) { 

    $rootScope.$on('$stateChangeStart', function(evt, to, params) { 
     if (to.redirectTo) { 
     evt.preventDefault(); 
     $state.go(to.redirectTo, params) 
     } 
    }); 
}]); 

而且,我刪除了重定向當前坐在operationsController.js

angular.module('uiRouterApp') 
    .controller('operationsController', function($state, $stateParams, $rootScope) { 
    var vm = this; 

    //if ($state.current.name === 'operations') $state.go('operations.new'); 

而且,所有以上僅僅是讓新的狀態 - 無網址。由於該解決方案將變得更加容易,如果我們只是介紹url: '/new'

.state('operations', { 
    url: '/operations', 
    .. 
}) 
.state('operations.new', { 
    //url: '', 
    url: '/new', 

檢查plunker here

所以,這樣我們給生活給我們的路由。現在是時候讓細節工作了。要做到這一點,我們需要更多 - there is another updated plunker

首先,我們將得到全新controller到兩個子狀態的觀點:

.state('operations.new', { 
    url: '', 
    views: { 
    'detail': { 
     templateUrl: 'operations.detail.html', 
     controller: 'detailCtrl as dc',   // here new controller 
    ... 
}) 
.state('operations.detail', { 
    url: '/:id', 
    views: { 
    'detail': { 
     templateUrl: 'operations.detail.html', 
     controller: 'detailCtrl as dc',   // here new controller 
    ... 

這可能是兩個相同的控制器,因爲我們將繼續決定新的或現有的內容$stateParams.id。這將是其實現:

.controller('detailCtrl', function($scope, $state, $stateParams) { 
    var op = $scope.op; 

    op.operation = {id:op.operations.length + 1}; 

    if ($stateParams.id) { 
     for (var i = 0; i < op.operations.length; i++) { 
     if (op.operations[i].id == $stateParams.id) { 
      op.operation = op.operations[i]; 
      break; 
     } 
     } 
    } 
}) 

我們保持原來的做法,並設置只是如果$stateParams.id選擇op.operation。如果不是,我們創建新項目,id正確遞增。

現在我們只調整父控制器,爲不保存現有的,只是新:

.controller('operationsController', function($state, $stateParams, $rootScope) { 
    var vm = this; 

    //if ($state.current.name === 'operations') $state.go('operations.new'); 

    vm.operation = {}; 

    /*$rootScope.$on('$stateChangeStart', 
        function(event, toState, toParams, fromState, fromParams) { 
     if (toParams) { 
     if (toParams.id) { 
      for (var i = 0; i < vm.operations.length; i++) { 
      if (vm.operations[i].id == toParams.id) { 
       vm.operation = vm.operations[i]; 
       break; 
      } 
      } 
     } 
     } 
    });*/ 

    vm.save = function() { 

     if(vm.operations.indexOf(vm.operation) >= 0){ 
     return; 
     } 
     if (vm.operation.name 
     && vm.operation.description 
     && vm.operation.quantity) { 
     vm.operations.push(vm.operation); 
     vm.operation = {id: vm.operations.length + 1}; 
     } 
    }; 

檢查complete version here

+0

你是一個生命的救星。我真的用盡了我的智力法力來找出像「抽象」等狀態設置的所需配置。保存我的是1)添加'redirectTo'設置和'redirector'; 2)將'controller'設置添加到狀態,因爲現在'$ stateParams.id'在每個路由改變(即選擇操作)時被更新。現在沒有什麼能阻止我們征服世界_hehehe_:D乾杯,隊友! –

+0

如果這是工作,我真的很高興。享受強大的UI路由器,先生;) –