Запуск функции контроллера при каждом открытии/отображении представления


Я создаю приложение с angular+ionic, которое использует классическое трехкнопочное меню внизу с тремя ионными вкладками в нем. Когда пользователь нажимает на вкладку, которая открывает шаблон через интерфейс-маршрутизатор.

у меня есть такие состояния:

$stateProvider
  .state('other', {
    url: "/other",
    abstract: true,
    templateUrl: "templates/other/other.html"
})

в шаблоне я делаю что-то вроде:

<ion-nav-view name="other" ng-init="doSomething()"></ion-nav-view>

Я знаю, что могу написать функцию doSomething() в своем контроллере и просто вызвать ее вручную. Это дает мне ту же проблему, хотя. Кажется, я не могу понять как вызвать функцию doSomething () более одного раза, когда кто-то открывает это представление.

прямо сейчас функция doSomething () вызывается просто отлично, но только в первый раз, когда пользователь открывает вид/вкладку. Я хотел бы вызвать функцию (для обновления геолокации) всякий раз, когда пользователь открывает это представление или вкладку.

что было бы правильным способом реализовать это?

Спасибо за помощь !

9 79

9 ответов:

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

<ion-nav-view ng-controller="indexController" name="other" ng-init="doSomething()"></ion-nav-view>

и в вашем контроллере:

app.controller('indexController', function($scope) {
    /*
        Write some code directly over here without any function,
        and it will be executed every time your view loads.
        Something like this:
    */
    $scope.xyz = 1;
});

Edit: вы можете попытаться отслеживать изменения состояния, а затем выполнить некоторый код при изменении маршрута и посещении определенного маршрута, например пример:

$rootScope.$on('$stateChangeSuccess', 
function(event, toState, toParams, fromState, fromParams){ ... })

вы можете найти более подробную информацию здесь: События Изменения Состояния.

по умолчанию ваши контроллеры были кэшированы, и именно поэтому ваш контроллер сработал только один раз. Чтобы отключить кэширование для определенного контроллера, вы должны изменить свой .config(..).state и выберите до false. например :

  .state('myApp', {
    cache: false,
    url: "/form",
    views: {
      'menuContent': {
        templateUrl: "templates/form.html",
        controller: 'formCtrl'
      }
    }
  })

для дальнейшего чтения, пожалуйста, посетите http://ionicframework.com/docs/api/directive/ionNavView/

после ответа и ссылки от AlexMart, что-то вроде это работает:

.controller('MyCtrl', function($scope) {
  $scope.$on('$ionicView.enter', function() {
     // Code you want executed every time view is opened
     console.log('Opened!')
  })
})

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

Просмотр Жизненного Цикла

для повышения производительности мы улучшили способность Ionic кэшировать элементы представления и данные области. После инициализации контроллера он может сохраняться в течение всего срока службы приложения; он просто скрыт и удален из цикла часов. Поскольку мы не перестраиваем область, мы добавили события, которые мы должны слушать при повторном входе в часовой цикл.

чтобы увидеть полное описание и $ ionicview события перейти к: http://ionicframework.com/blog/navigating-the-changes/

почему бы вам не отключить кэш представление с cache-view= "false"?

на ваш взгляд, добавьте это в Ion-nav-view следующим образом:

<ion-nav-view name="other" cache-view="false"></ion-nav-view>

или в вашем stateProvider:

$stateProvider.state('other', {
   cache: false,
   url : '/other',
   templateUrl : 'templates/other/other.html'
})

либо один сделает ваш контроллер вызывается всегда.

например к @Michael Trouw,

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

.controller('exampleCtrl',function($scope){
$scope.$on('$ionicView.enter', function(){
        // Any thing you can think of
        alert("This function just ran away");   
    });
})

вы можете иметь больше примеров гибкости, таких как $ionicView.beforeEnter ->, который работает, прежде чем показывать представления. И это еще не все.

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

$ionicConfigProvider.views.maxCache(0);

иначе, то, как я работал для меня, делал

$scope.$on("$ionicView.afterLeave", function () {
     $ionicHistory.clearCache();
}); 

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

Это, вероятно, то, что вы искали:

Ionic кэширует ваши представления и, следовательно, ваши контроллеры по умолчанию (максимум 10) http://ionicframework.com/docs/api/directive/ionView/

есть события, которые вы можете подключить, чтобы ваш контроллер делал определенные вещи на основе этих ионных событий. смотрите здесь для примера: http://ionicframework.com/blog/navigating-the-changes/

У меня была аналогичная проблема с ionic, где я пытался загрузить родную камеру, как только я выбираю вкладку камеры. Я решил проблему, установив контроллер на компонент ion-view для вкладки камеры (в вкладках.html), а затем вызов метода $scope, который загружает мою камеру (addImage).

в www / templates / tabs.HTML-код

  <ion-tab title="Camera" icon-off="ion-camera" icon-on="ion-camera" href="#/tab/chats" ng-controller="AddMediaCtrl" ng-click="addImage()">
    <ion-nav-view  name="tab-chats"></ion-nav-view>
  </ion-tab>

метод addImage, определенный в AddMediaCtrl загружает собственную камеру каждый раз, когда пользователь нажимает вкладку "камера". Я сделал не нужно изменить что-нибудь в угловом кэше, чтобы это работало. Надеюсь, это поможет.