离子框架ionicView.entered事件被触发两次

时间:2015-05-14 11:38:15

标签: javascript angular-ui-router ionic-framework

我正在使用此视图变为活动时触发的ionicView事件,并且我正在使用您在创建项目时可以重复使用的侧边菜单模板。似乎如果我在AppCtrl中放置一个$ ionicView.entered事件的监听器(侧面菜单模板使用的那个,它属于ui-router配置中的抽象状态),它会连续两次调用子视图(例如,当使用app.someotherview作为状态时)。

我不知道这是否是预期的行为,因为无论我是否更改子视图(menuContent视图),我都希望它只会触发一次。

我想知道这是否是预期的行为,如果是这样,我怎样才能在每次显示侧边菜单模板时触发一次事件。

这就是我写的:

这是来自应用程序模块:

.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'); 

然后AppCtrl是这样的:

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);
    });
}); 

菜单模板:

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

5 个答案:

答案 0 :(得分:10)

一个简单的解决方法是:

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

答案 1 :(得分:2)

我发现模拟onEnter事件的最佳选择是在视图控制器中使用:

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

}

答案 2 :(得分:1)

您可以通过执行以下操作全局禁用离子使用的缓存机制:

$ionicConfigProvider.views.maxCache(0);

我自己没试过。

否则,对我有用的最佳方式是

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

这是为了在每次再次输入时离开视图之前清除缓存以重新运行控制器。

答案 3 :(得分:0)

试试$ionicView.afterEnter。这对我来说只有一次。 URL

答案 4 :(得分:0)

起初我使用Florian's answer但是注意到在我的情况下它只是根问题的症状,因为这不会发生在所有控制器上,只有这一个。

在我的情况下,它发生是因为我试图incrementally migrate from Ionic/AngularJS v1 to Ionic/AngularJS v2

我在模板中添加了controllerAs

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

但我忘记删除app.js中的控制器参考:

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

所以在我的情况下,解决方案是:

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