web-dev-qa-db-fra.com

Exécuter une fonction de contrôleur chaque fois qu'une vue est ouverte / affichée

Je construis une application avec angular + ionic qui utilise un menu classique à trois boutons avec trois onglets d'ion. Lorsqu'un utilisateur clique sur un onglet, ce modèle s'ouvre via ui-router.

J'ai des états comme celui-ci:

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

Dans le modèle, je fais quelque chose comme:

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

Je suis conscient que je peux écrire la fonction doSomething () dans mon contrôleur et l'appeler simplement manuellement. Cela me donne le même problème cependant. Je n'arrive pas à comprendre comment appeler la fonction doSomething () plus d'une fois, chaque fois que quelqu'un ouvre cette vue.

Pour le moment, la fonction doSomething () est appelée correctement, mais seulement la première fois que cette vue/cet onglet est ouvert par l'utilisateur. J'aimerais appeler une fonction (pour mettre à jour la géolocalisation) lorsqu'un utilisateur ouvre cette vue ou cet onglet.

Quelle serait la bonne façon de mettre cela en œuvre?

Merci de votre aide!

79
Jorre

Si vous avez affecté un certain contrôleur à votre vue, celui-ci sera appelé à chaque chargement de votre vue. Dans ce cas, vous pouvez exécuter du code dans votre contrôleur dès qu'il est appelé, par exemple:

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

Et dans votre contrôleur:

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: Vous pouvez essayer de suivre les changements d'état, puis exécuter du code lorsque la route est modifiée et qu'une route donnée est visitée, par exemple:

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

Vous pouvez trouver plus de détails ici: Événements de changement d'état .

45
Manish Kr. Shukla

Par défaut, vos contrôleurs étaient en cache et c'est pourquoi votre contrôleur n'a été déclenché qu'une seule fois. Pour désactiver la mise en cache d'un certain contrôleur, vous devez modifier votre .config(..).state et définir l'option cache sur false. par exemple :

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

pour plus de lecture s'il vous plaît visitez http://ionicframework.com/docs/api/directive/ionNavView/

86
Yakob Ubaidi

Suivi de la réponse et du lien de AlexMart , quelque chose comme ceci fonctionne:

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

J'ai fait face au même problème, et je laisse ici la raison de ce comportement pour tous les autres avec le même problème.

Voir LifeCycle

Afin d'améliorer les performances, nous avons amélioré la capacité d'Ionic à mettre en cache les éléments de vue et les données de portée. Une fois qu'un contrôleur est initialisé, il peut persister tout au long de la vie de l'application. elle est simplement cachée et retirée du cycle de la montre. Puisque nous ne reconstruisons pas la portée, nous avons ajouté des événements pour lesquels nous devrions écouter lorsque nous entrons dans le cycle de surveillance.

Pour voir la description complète et les événements $ ionicView, allez à: http://ionicframework.com/blog/navigating-the-changes/

12
AlexMart

Pourquoi ne désactivez-vous pas le cache de vues avec cache-view = "false"?

A votre avis, ajoutez ceci à la vue ion-nav-view comme ceci:

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

Ou dans votre fournisseur d’état:

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

Soit on fera appeler votre contrôleur toujours.

8
Diogo Medeiros

Par exemple à @Michael Trouw,

dans votre contrôleur, mettez ce code. cela fonctionnera à chaque fois que cet état est entré ou actif, vous n'avez pas à vous soucier de la désactivation du cache, c'est une meilleure approche.

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

Vous pouvez avoir plus d'exemples de flexibilité comme $ ionicView.beforeEnter -> qui s'exécute avant qu'une vue ne soit affichée. Et il y en a plus.

5
Wang'l Pakhrin

Compte tenu de la capacité d'Ionic à mettre en cache les éléments de vue et les données de portée mentionnés ci-dessus, cela pourrait être une autre façon de faire, si vous souhaitez exécuter le contrôleur chaque fois que la vue est chargée. Vous pouvez désactiver globalement le mécanisme de cache utilisé par ionic en procédant comme suit:

$ionicConfigProvider.views.maxCache(0);

Sinon, la façon dont je l'avais travaillé pour moi faisait

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

Cela consiste à vider le cache avant de quitter la vue pour réexécuter le contrôleur à chaque nouvelle entrée.

2
Rajush

C'est probablement ce que vous cherchiez:

Ionic met en cache vos vues et donc vos contrôleurs par défaut (max. 10) http://ionicframework.com/docs/api/directive/ionView/

Vous pouvez vous connecter à certains événements pour laisser votre contrôleur effectuer certaines tâches en fonction de ces événements ionic. voir ici pour un exemple: http://ionicframework.com/blog/navigating-the-changes/

1
Michael Trouw

J'avais un problème similaire avec ionic où j'essayais de charger la caméra native dès que je sélectionnais l'onglet Caméra. J'ai résolu le problème en configurant le contrôleur sur le composant ion-view de l'onglet caméra (dans tabs.html), puis en appelant la méthode $ scope qui charge ma caméra (addImage).

Dans 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>

La méthode addImage, définie dans AddMediaCtrl, charge la caméra native chaque fois que l'utilisateur clique sur l'onglet "Caméra". J'ai pas avoir à changer quoi que ce soit dans le cache angular pour que cela fonctionne. J'espère que ça aide.

0
chukkwagon