2015-05-14 4 views
5

Sto giocando con questi eventi ionicView che vengono attivati ​​ogni volta che le visualizzazioni diventano attive e sto utilizzando il modello di menu laterale che è possibile riutilizzare durante la creazione del progetto. Sembra che se metto un listener per l'evento $ ionicView.entered in AppCtrl (quello usato dal template del menu laterale, che appartiene a uno stato astratto nella configurazione del router), viene chiamato due volte di seguito per qualsiasi delle sottoview (come quando si usa app.someotherview come stato).Ionic framework ionicView.entered evento sparato due volte

Non so se questo è il comportamento previsto perché dalla documentazione mi aspetterei che si attivi solo una volta, non importa se cambio la vista secondaria (la vista menuContent).

Mi piacerebbe sapere se questo è un comportamento previsto e in tal caso, come faccio ad avere un evento sparato solo una volta ogni volta che viene visualizzato il modello del menu laterale.

Questo è quello che ho scritto:

Questo è dal modulo applicativo:

.config(function($stateProvider, $urlRouterProvider, $httpProvider) { 
    $stateProvider 

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

    .state('app.overview', { 
    url: "/overview", 
    views: { 
     'menuContent': { 
     templateUrl: "templates/overview.html", 
     controller: 'OverviewCtrl' 
     } 
    } 
    }) 

    .state('login', { 
    url: "/login", 
    templateUrl: "templates/identificationscreen.html", 
    controller: "IdentificationCtrl" 
    }) 

    .state('app.agenda', { 
    url: "/agenda", 
    views: { 
     'menuContent': { 
     templateUrl: "templates/agenda.html", 
     controller: 'AgendaCtrl' 
     } 
    } 
    }); 

    $httpProvider.interceptors.push('credentialsInjector'); 

    // if none of the above states are matched, use this as the fallback 
    $urlRouterProvider.otherwise('/login'); 

Poi l'AppCtrl è questo:

angular.module('dashboard.controllers.app', []) 
.controller('AppCtrl', function($scope, $ionicModal, $timeout, $ionicSideMenuDelegate, authService, $state) { 
    $scope.logout = function() { 
     authService.logout(); 
     $state.go('login'); 
    }; 

    $scope.$on('$ionicView.enter', function(){ //This is fired twice in a row 
     console.log("App view (menu) entered."); 
     console.log(arguments); 
    }); 

    $scope.$on('$ionicView.leave', function(){ //This just one when leaving, which happens when I logout 
     console.log("App view (menu) leaved."); 
     console.log(arguments); 
    }); 
}); 

il modello di menu:

<ion-side-menus enable-menu-with-back-views="false"> 
    <ion-side-menu-content edge-drag-threshold="true"> 
    <ion-nav-bar class="bar-stable"> 
     <ion-nav-back-button> 
     </ion-nav-back-button> 
     <ion-nav-buttons side="left"> 
     <button class="button button-icon button-clear ion-navicon" menu-toggle="left"> 
     </button> 
     </ion-nav-buttons> 
    </ion-nav-bar> 
    <ion-nav-view name="menuContent"></ion-nav-view> 
    </ion-side-menu-content> 

    <ion-side-menu side="left"> 
    <ion-header-bar class="bar-stable"> 
     <h1 class="title">APPoint!</h1> 
    </ion-header-bar> 
    <ion-content> 
     <ion-list> 
     <ion-item nav-clear menu-close href="#/app/overview"> 
      Overview 
     </ion-item> 
     <ion-item nav-clear menu-close href="#/app/agenda"> 
      Agenda 
     </ion-item> 
     <ion-item nav-clear menu-close ng-click="logout()"> 
      Logout 
     </ion-item> 
     </ion-list> 
    </ion-content> 
    </ion-side-menu> 
</ion-side-menus> 
+0

@andrian hai la soluzione per questo problema? – Webruster

risposta

0

Prova $ionicView.afterEnter. Quello spara solo una volta per me. URL

+0

non funziona per me - si chiama anche due volte –

1

È possibile disattivare globalmente il meccanismo di caching utilizzato da ionica facendo:

$ionicConfigProvider.views.maxCache(0); 

Non ho provato che da solo però.

Altrimenti, il modo migliore che ha funzionato per me stava facendo

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

Questo è quello di cancellare la cache prima di lasciare la fine di re-run di controllo ogni volta che si entra di nuovo.

1

L'opzione migliore che ho trovato per simulare onEnter evento è stato quello di utilizzare in vista del regolatore:

$scope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) { 
if (toState.name == "stateName") 
    doSomething(); 

} 
+0

Mille grazie per te, risolvi il mio problema! – QViet

9

Una soluzione semplice è:

$scope.$on('$ionicView.enter', function(ev) { 
    if(ev.targetScope !== $scope) 
     return; 
    // Your code which should only run once 
}); 
+1

Semplice ed elegante. Molte grazie :) – VinceOPS

+0

Grazie, questo funziona. Ma voglio ora so perché funziona in questo modo. In particolare, è strano che 'ev.targetScope.id === $ scope.id' anche se' ev.targetScope! == $ scope'! –

0

In un primo momento ho usato Florian's answer ma notato che nel mio caso è solo un sintomo di un problema di root, perché questo non accade a tutti i controller, solo questo.

Nel mio caso, succede perché stavo provando a incrementally migrate from Ionic/AngularJS v1 to Ionic/AngularJS v2.

ho aggiunto controllerAs nel mio modello:

<ion-view view-title="Avatar » Instruments" ng-controller="AvatarInstrumentsCtrl as vm"> 

ma ho dimenticato di rimuovere il riferimento del regolatore nel mio app.js:

.state('app.avatar-instruments', { 
     url: "/avatar/instruments", 
     views: { 
     'menuContent': { 
      templateUrl: "templates/avatar/instruments.html", 
      controller: 'AvatarInstrumentsCtrl' 
     } 
     } 
    }) 

Così nel mio caso la soluzione è:

.state('app.avatar-instruments', { 
     url: "/avatar/instruments", 
     views: { 
     'menuContent': { 
      templateUrl: "templates/avatar/instruments.html" 
     } 
     } 
    })