Подтвердить что ты не робот

Объём и реализация контроллера с помощью маршрутизатора ui

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

Может кто-нибудь объяснить, когда контроллеры получают экземпляр? Под вложенными маршрутами все представления имеют один контроллер и область видимости? Что происходит, когда я переключаю состояния и возвращаюсь в состояние, создается ли другой экземпляр контроллера?

Ниже приведены мои маршруты (файл конфигурации):

.config (googleAnalyticsCordovaProvider, $stateProvider, $urlRouterProvider, IdleProvider, KeepaliveProvider) ->

   $stateProvider

  .state('app', {
    url: '/app',
    abstract: true,
    templateUrl: 'templates/menu.html',
    controller: 'AppController'
  })

  .state('app.pincode', {
    url: '/pincode',
    views: {
      menuContent: {
        templateUrl: 'templates/pincode-yield.html',
        controller: 'PincodeController'
      }
    }
  })

  .state('app.pincode.create', {
    url: '/create',
    views: {
      pincode: {
        templateUrl: 'templates/pincode-create.html',
        controller: 'PincodeController'
      }
    }
  })

  .state('app.pincode.pincodeLogin', {
    url: '/login',
    views: {
     pincode: {
        templateUrl: 'templates/pincode-login.html',
        controller: 'PincodeController'
      }
    }
  })

  .state('app.pincode.settings', {
    url: '/settings',
    views: {
      pincode: {
        templateUrl: 'templates/settings.html',
        controller: 'PincodeController'
      }
    }
  })
4b9b3361

Ответ 1

Чтобы получить более подробные ответы, мы можем/должны соблюдать исходный код и проверить документацию . Позвольте мне попытаться объяснить все три вопроса (а также привести из кода и документа).

1. Когда создаются экземпляры контроллеров?

Здесь мы можем наблюдать код директивы ui-view:

[$ViewDirective.$inject = \['$state', '$injector', '$uiViewScroll', '$interpolate'\];][1]

Контроллеры связаны с видами. Те views, которые определены внутри .state() как объект views:

.state('...', {
  // The view definition
  views : {
    '' : {
      template: ...
      controller: ...
      resolve: ..
    }
  },
  resolve: ...
}

Итак, всякий раз, когда view (the ui-view) заполняется настройками, определенными внутри представления состояния, он действует почти как стандартная , но расширенная директива.

1) Шаблон найден,
2) Решения разрешены
...
x) Создан контроллер...

Просмотр целей (директивы ui-view) могут использовать имена и могут быть заполнены разными состояниями в иерархии.

Это может означать, что внутри одного представления может быть содержимое (например, title), определяемое parent, а также замененное на дочерний strong >

// parent
.state('parent', {
  views : {
    '' : {...} // the main parent view, with ui-view="title"
    '[email protected]' : { ...} // here we go and fill parent ui-view="title"
  },
  ...
}

// child
.state('parent.child', {
  views : {
    'title' : { ...} // here we change the parent target ui-view="title"
  },
  ...
}

Вышеуказанное определение состояния будет (всякий раз, когда мы переходим из этих двух состояний):

  • $state.go('parent') - представление (шаблон, контроллер...), определенное в '[email protected]' : { ...}, будет введено в целевой ui-view="title" и создаваться как описано выше

  • $state.go('parent.child') - почти то же самое, только представление будет взято из состояния child/view defintion 'title' : { ...}. Это заменит содержимое ui-view="title" и будет создано таким образом, как описано выше.

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

2. Под вложенными маршрутами все представления совместно используют один контроллер и область видимости?

Простой ответ НЕТ, существует общий не общий доступ.

Фактически, каждый контроллер имеет собственную область, созданную из области представления родительского представления. Во-первых, документация:

Что наследуют дочерние государства из родительских состояний?

...

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

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

Вполне возможно, что у вас есть вложенные состояния, шаблоны которых заполняют u-views в разных не-вложенных местах на вашем сайте. В этом случае вы не можете ожидать доступа к переменным области представлений родительского состояния в представлениях дочерних состояний.

Итак, всякий раз, когда есть наш controller (ну представление с шаблоном, контроллер...), введенный в родительскую цель ui-view="...", он получает наследуемую область:

newScope = scope.$new();

Это в двух словах означает, что объекты JS (например, scope.Model = {}) могут совместно использоваться дочерними и родительскими.

$scope.Model.id = 1; // will refer to the same id in both parent & child

Однако, основные типы Javascript не передаются по ссылке, поэтому их значения автоматически не синхронизируются между областями:

// set in parent
$scope.id = 1;
// in child after inherted still === 1
$scope.id = 2; // now 2 for a child, different value in parent - still === 1

Здесь стоит прочитать больше о прототипическом наследовании:
Каковы нюансы объема прототипа/прототипного наследования в AngularJS?

3. Что происходит, когда я переключаю состояния и возвращаюсь в состояние - создается ли еще один контроллер?

Это зависит.

Если родительский под просмотр (помните ui-view="title" выше) заменяется дочерним видом, а затем он заново создается (переход от дочернего к родительскому) - такой контроллер будет повторно инициализирован (обсуждается выше).

Но когда мы говорим о основном родительском представлении (обычно без имени), который представляет родительский (например, неназванное представление ниже с контроллером ParentMainCtrl)

.state('parent', {
  views : {
    '' : {  //  // the main parent view
      controller: 'ParentMainCtrl',
    }
    '[email protected]'
    '[email protected]'
  },

Тогда мы можем быть уверены, что такой контроллер НЕ повторно создан. Он живет во время жизни всех его детей, плюс родительский (не выбрано дочернее состояние).

Чтобы повторно загрузить этот просмотр/контроллер, мы должны использовать опцию reload

$state.go(to, params, options)

... Параметры Опция объекта. Возможные варианты:

  • ...
  • перезагрузить - {boolean=false}. Если значение true приведет к переходу, даже если состояние или параметры не изменились, то есть перезагрузка того же состояния. Он отличается от reloadOnSearch, потому что вы будете использовать его, когда хотите принудительно перезагрузить, когда все будет одинаково, включая параметры поиска.

Надеюсь, что это поможет. Для получения дополнительной информации ознакомьтесь с этими ресурсами:

Ответ 2

Контроллеры получают экземпляр при каждом посещении определенного состояния. Например, при посещении app.pincode.pincodeLogin в первый раз создаются один AppController и два PincodeControllers, каждый со своим собственным представлением, предполагая, что вы получили правильные шаблоны. Переключение на 'app.pincode.settings' приведет к уничтожению самого внутреннего контроллера и замене его новым, хотя два контроллера выше в иерархии не будут затронуты. Scopes следуют стандартным шаблонам наследования AngularJS, они не изолированы.

Вероятно, вы захотите удалить контроллеры в дочерних состояниях (и обработать бизнес-логику в родительском контроллере) или иметь отдельный контроллер для каждого состояния - тот же контроллер для разных шаблонов и представлений обычно является признаком плохого дизайна.

Ответ 3

Контроллеры получают экземпляр, когда соответствующие представления загружаются в первый раз.

Например, если у вас есть 3 вкладки, связанные с 3 контроллерами, тогда контроллер, связанный с представлением по умолчанию, создает экземпляр First. Затем, когда вы загружаете другие представления, связанные контроллеры также получают экземпляр.

Но интересно, как только представление загружается в DOM - оно кэшируется по умолчанию. Когда представление перемещается от него, его элемент остается в DOM, а его область отключена от цикла $watch. При навигации к уже кэшированному представлению его область снова подключается, а существующий элемент, оставшийся в DOM, становится активным.