AngularJS:具有路由的多个视图,不会丢失范围

时间:2013-04-18 14:15:44

标签: angularjs angularjs-scope angularjs-routing

我正在尝试实现经典列表/详细信息UI。单击列表中的项目时,我想显示该项的编辑表单,同时仍显示列表。我正在尝试解决Angular的每页1个视图限制,并决定将所有URL路由到同一个控制器/视图。 (也许这是我问题的根源,我对其他选择持开放态度。)

路由:

$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. 单击编辑链接时,控制器将使用新范围重新实例化,因此我必须重新初始化“用户”列表。 (在一个更复杂的例子中,我可以从存储绑定到模型的用户输入,这也会丢失。)我更愿意保留前一个路径的范围。
  2. 我更喜欢使用一个单独的控制器(或者,正如许多其他Angular开发者所抱怨的那样,能够拥有多个显示的视图!)但这会导致同样的失去范围的问题。

4 个答案:

答案 0 :(得分:14)

尝试使用ui-router:http://github.com/angular-ui/ui-router

与角度默认路由相比,它们具有嵌套视图和更简单的状态管理: - )

答案 1 :(得分:7)

核心AngularJS不支持多个视图。您可以使用此库来支持页面上任意数量的嵌套视图,其中每个级别都使用自己的控制器和模板独立配置:

http://angular-route-segment.com

使用比ui-router简单得多。示例配置可能如下所示:

$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});

答案 2 :(得分:1)

我发现Angular Multi View是这种情况的天赐之物。它允许您在路径更改时保留范围,并允许多个控制器共享相同的路径而不嵌套您的视图

如果您的网页上有超过2个观看次数,我建议使用Angular Multi View。否则,当使用ui-router时,嵌套多个视图会非常快速地混乱。

答案 3 :(得分:0)

我想出了同样的问题,当他们不是绝对不可避免的时候,我个人不喜欢插件。我只是将单件部分移动到服务中。

在我的情况下有:id [/:mode] routes,如果用户只更改模式或id,我想做出不同的反应。因此,我必须知道以前的身份。

因此,有一个使用activate方法的服务可以更新其状态。每次使用以下代码重新初始化范围。

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进行比较,并做出不同的反应。