2013-04-18 75 views
12

我想實現一個經典的列表/細節UI。點擊列表中的項目時,我想顯示該項目的編輯表格,同時仍顯示列表。我正在嘗試解決Angular的1-view-per-page限制,並決定將所有URL路由到同一個控制器/視圖。 (也許這是我的問題的根源,我接受的替代品。)AngularJS:多個視圖與路由而不丟失範圍

路由:

$routeProvider 
    .when('/list', { templateUrl: '/Partials/Users.html', controller: UserController }) 
    .when('/edit/:UserId', { templateUrl: '/Partials/Users.html', controller: UserController }) 
    .otherwise({ redirectTo: '/list' }); 

視圖(/Partials/Users.html):

<!-- List of users --> 
<div ng-repeat="user in Users"> 
    <a href="*/edit/{{ user.Id }}">Edit {{ user.Name }}</a> 
</div> 

<!-- Edit form --> 
<div> 
    {{ SelectedUser.Name }} 
</div> 

控制器:

function UserController($scope, $routeParams) { 
    // the model for the list 
    $scope.Users = GetUserListFromService(); 

    // the model for the edit form 
    if ($routeParams.UserId != null) 
     $scope.SelectedUser = GetUserFromService($routeParams.UserId); 
} 

問題:

  1. 單擊編輯鏈接時,控制器將重新實例化一個新範圍,因此必須重新啓動「用戶」列表。 (在一個更復雜的例子中,我可以從用戶的輸入存儲綁定到模型,這也會丟失。)我寧願保留範圍從以前的路線。我傾向於使用單獨的控制器(或者像許多其他Angular開發人員所抱怨的那樣,具有多個顯示視圖的能力!),但這會導致丟失範圍的相同問題。
+0

可能重複的[Angularjs,路由之間的範圍](http://stackoverflow.com/questions/13882077/angularjs-passing-scope-between-routes) –

回答

14

嘗試使用ui-router:http://github.com/angular-ui/ui-router

他們嵌套的意見,更容易管理的狀態比角度默認路由:-)

+1

謝謝!遵循他們的教程和示例並不容易,因此對於試圖實現相同模式的其他人,我建議您爲每個視圖創建一個「狀態」並使用嵌套狀態來允許範圍共享。 – Keith

+0

我想看看你是如何做到這一點的。我在選擇路由器時遇到了麻煩。 – Timothy

+2

@timothy https://github.com/dotJEM/angular-routing是UI-Router的一個替代方案,它有一個簡單的視圖(沒有視圖@視圖的魔術等等......只是純粹和簡單的命名views)......如果這是你遇到麻煩的原因(UI-Router視圖模型已經受到了相當多的批評,並且很多人似乎很難在非常簡單的情況下使用它) – Jens

1

我發現Angular Multi View成爲這個場景一大福音。它可以讓您在路線更改時保留範圍,並讓多個控制器共享相同的路線而不會嵌套您的視圖

如果您的頁面上有2個以上的視圖,我建議使用Angular Multi View。否則,在使用ui-router時,嵌套多個視圖的速度會非常快。

7

核心AngularJS不支持多個視圖。你可以使用這個庫用於這一目的,它支持的頁面,其中每個級別都有自己的控制器和模板獨立配置上嵌套視圖的任何金額:

http://angular-route-segment.com

這是很簡單的比用戶界面 - 使用路由器。示例配置可以是這樣的:

$routeSegmentProvider. 

when('/section1',   's1.home'). 
when('/section1/prefs', 's1.prefs'). 
when('/section1/:id',  's1.itemInfo.overview'). 
when('/section1/:id/edit', 's1.itemInfo.edit'). 
when('/section2',   's2'). 

segment('s1', { 
    templateUrl: 'templates/section1.html', 
    controller: MainCtrl}). 

within(). 

    segment('home', { 
     templateUrl: 'templates/section1/home.html'}). 

    segment('itemInfo', { 
     templateUrl: 'templates/section1/item.html', 
     controller: Section1ItemCtrl, 
     dependencies: ['id']}). 

    within(). 

     segment('overview', { 
      templateUrl: 'templates/section1/item/overview.html'}). 

     segment('edit', { 
      templateUrl: 'templates/section1/item/edit.html'}). 

     up(). 

    segment('prefs', { 
     templateUrl: 'templates/section1/prefs.html'}). 

    up(). 

segment('s2', { 
    templateUrl: 'templates/section2.html', 
    controller: MainCtrl}); 
0

我想出了同樣的問題,我personnaly不喜歡的插件的時候都沒有絕對少不了。我只是將單身人士的部分移到了服務中。

在我的情況下有:id [/:mode]路由,如果用戶只改變模式或ID,我想以不同的方式作出反應。因此,我必須知道以前的ID。

因此,有一種服務激活方法,它會更新其狀態。每次使用以下代碼重新初始化作用域。

module.controller('MyController', ['$scope', '$routeParams', 'navigator', function($scope, $routeParams, navigator) { 
    var id = null; 
    var mode = null; 

    if (typeof($routeParams.id)!='undefined') 
    { 
     id = $routeParams.id; 
    } 

    if (typeof($routeParams.mode)!='undefined') 
    { 
     mode = $routeParams.mode; 
    } 

    navigator.activate(id, mode); 

    $scope.items = navigator.items; 
    $scope.activeItem = navigator.activeItem; 
    $scope.modes = navigator.modes; 
    $scope.activeMode = navigator.activeMode; 
}]); 

在激活方法我可以比較ID,以單身的activeItem.id和反應是不同的。