AngularJS: несколько просмотров с маршрутизацией без потери объема

Я пытаюсь реализовать классический интерфейс списка/деталей. Когда вы нажимаете элемент в списке, я хочу отобразить форму редактирования для этого элемента, все еще отображая список. Я пытаюсь обойти ограничение Angular 1-view-per-page и решил сделать это, указав все URL-адреса на один и тот же контроллер/просмотр. (Возможно, это корень моей проблемы, и я открыт для альтернатив.)

Routing:

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

Проблемы:

  • При нажатии ссылки на редактирование контроллер восстанавливается с новой областью, поэтому мне нужно перезапустить список "Пользователи". (В более сложном примере я мог бы получить данные от пользователя, сохраненного в привязке к модели, и это также потеряется.) Я предпочел бы сохранить область действия с предыдущего маршрута.
  • Я бы предпочел использовать отдельный контроллер (или, как многие другие Angular разработчики жаловались, возможность иметь несколько отображаемых представлений!), но это приводит к той же проблеме потери области.

Ответ 1

Попробуйте использовать ui-router: http://github.com/angular-ui/ui-router.

У них есть вложенные представления и более простое управление состоянием, чем angular маршрутизация по умолчанию: -)

Ответ 2

В ядре 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});

Ответ 3

Я нашел Angular Multi View, чтобы стать находкой для этого сценария. Он позволяет сохранять область по мере изменения маршрута и позволяет нескольким контроллерам совместно использовать один и тот же маршрут, не вставляя ваши представления.

Я рекомендую Angular Multi View, если на вашей странице более 2 просмотров. В противном случае при использовании ui-router вложение нескольких видов становится очень беспорядочным.

Ответ 4

Я столкнулся с той же проблемой, и я лично не люблю плагины, когда они не абсолютно неизбежны. Я только что перевел Singleton часть на службу.

В моем случае есть маршруты id [/: mode], и ​​я хочу реагировать по-другому, если пользователь меняет только режим или идентификатор. Таким образом, я должен знать предыдущий идентификатор.

Итак, есть служба с активированным методом, которая обновляет ее состояние. И область действия повторно инициализируется каждый раз с помощью следующего кода.

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 с singleton activeItem.id и реагировать по-разному.