【问题标题】:Ionic framework ionicView.entered event fired twice离子框架 ionicView.entered 事件触发了两次
【发布时间】:2016-03-18 19:01:32
【问题描述】:

我正在玩这个 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>

【问题讨论】:

  • @andrian 你有解决这个问题的方法吗?

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


【解决方案1】:

一个简单的解决方法是:

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

【讨论】:

  • 谢谢,这行得通。但是我想现在我知道它为什么会这样了。具体来说,ev.targetScope.id === $scope.id 即使ev.targetScope !== $scope
【解决方案2】:

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

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

}

【讨论】:

    【解决方案3】:

    您可以通过以下方式全局禁用 ionic 使用的缓存机制:

    $ionicConfigProvider.views.maxCache(0);
    

    不过,我还没有自己尝试过。

    否则,对我来说最好的方法就是做

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        起初我使用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"
                }
              }
            })
        

        【讨论】:

          猜你喜欢
          • 2014-08-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多