Управление несколькими представлениями в одном контроллере в AngularJS

Следуя шаблону MVC, один контроллер должен иметь возможность обрабатывать несколько представлений в AngularJS.

Например. У меня есть одно представление для отображения всех пользователей и одно для создания нового пользователя. Мой $routeProvider (отрывок) выглядит так:

app.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
      when('/showusers', {
        templateUrl: 'partials/showusers.html',
        controller: 'userController'
      }).   
      when('/createuser', {
        templateUrl: 'partials/showusers.html',
        controller: 'userController'
      })
  }]);

Оба представления используют несколько общих методов, таких как получение всех атрибутов пользователя. Доступ к этим общим методам осуществляется через файл factory.

userController (отрывок) в настоящее время выглядит так, где Users — это фабрика:

angular.module('supportModule').
  controller('userController', function($scope, Users) {
    var init = function(){
      $scope.users = Users.getAll();
      $scope.attributes = Users.getAttributes();
    }
    init();
  })

Проблема в том, что мне не нужно запрашивать Users.getAll();, когда я нахожусь в представлении createuser.

Конечно, я мог бы легко разобрать маршрут, используя $location, $routeProvider или чистый JS, а затем условно вызвать методы, но я полагаю, что в Angular есть более элегантный и эффективный способ :)
Что-то вроде типичных фреймворков MVC, где один контроллер имеет много действий - по одному для каждого представления.

Итак, мой вопрос:
Как элегантно вызывать методы на основе представления в контроллере, который управляет более чем одним представлением?


person Horen    schedule 31.07.2014    source источник
comment
Проверьте resolve.   -  person okm    schedule 31.07.2014
comment
вы можете обмениваться данными между контроллерами, используя ту же фабрику, которая использует методы... таким образом, вам не придется снова выполнять getAll...   -  person harishr    schedule 31.07.2014
comment
@HarishR Да, я знаю это и делаю это. Однако у меня снова было бы два контроллера, поэтому один контроллер для каждого представления, чего я пытаюсь избежать.   -  person Horen    schedule 31.07.2014
comment
в этом случае единственное решение, которое я могу придумать, - это иметь какой-то родительский html с ng-if/ng-include/ng-controller.. ui-router намного лучше справляется с такими вещами...   -  person harishr    schedule 31.07.2014


Ответы (1)


Вы можете использовать resolve: при настройке $routeProvider для передачи значений контроллеру в зависимости от согласованного маршрута.

app.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
      when('/showusers', {
        templateUrl: 'partials/showusers.html',
        controller: 'userController',
        resolve: {
          ctrlOptions: function () {
            return {
              getAllUsers: true,
            };
          }
        }
      }).
      when('/createuser', {
        templateUrl: 'partials/showusers.html',
        controller: 'userController',
        resolve: {
          ctrlOptions: function () {
            return {
              getAllUsers: false,
            };
          }
        }
      })
  }]);

а затем в контроллере вы можете ввести элемент, указанный в resolve:, следующим образом:

app.controller('userController', function ($scope, Users, ctrlOptions) {
  var init = function () {
    if (ctrlOptions.getAllUsers) {
      $scope.users = Users.getAll();
    }

    $scope.attributes = Users.getAttributes();
  };

  init();
});

Надеюсь это поможет.

person runTarm    schedule 31.07.2014
comment
Спасибо за ваш вклад. Я еще не использовал resolve, но, похоже, это очень удобно. Однако для моего примера я не вижу большого преимущества перед проверкой текущего маршрута в контроллере сразу. - person Horen; 01.08.2014
comment
Иногда вам не нужно добавлять разрешение для каждого маршрута, если вы этого не сделаете, angular вернет ошибку неизвестного провайдера. Есть ли способ избежать этого или, может быть, другой способ справиться с этим случаем? - person badr slaoui; 03.12.2015