12

我正在尝试实现一个经典的列表/详细信息 UI。单击列表中的项目时,我想显示该项目的编辑表单,同时仍显示列表。我正在尝试解决 Angular 的 1-view-per-page 限制,并决定通过将所有 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

4 回答 4

14

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

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

于 2013-04-18T14:59:20.927 回答
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});
于 2013-08-22T18:25:50.640 回答
1

我发现Angular Multi View是这种场景的天赐之物。它允许您在路由更改时保留范围,并允许多个控制器共享同一路由而无需嵌套您的视图

如果您的页面上有超过 2 个视图,我推荐使用 Angular Multi View。否则,当使用 ui-router 时,嵌套多个视图会很快变得混乱。

于 2013-08-07T16:41:18.930 回答
0

我想出了同样的问题,我个人不喜欢插件,因为它们不是绝对不可避免的。我刚刚将单例部分移至服务。

在我的情况下,有 :id[/:mode] 路由,如果用户也只更改模式或 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 进行比较并做出不同的反应。

于 2013-08-23T11:20:29.397 回答