我可以停止在onExit过渡到下一个状态? [英] Can I stop the transition to the next state in an onExit?

查看:162
本文介绍了我可以停止在onExit过渡到下一个状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个国家,A和B


  • 当我点击关闭按钮退出状态的我做了过渡到屏幕使用$ state.go状态B(屏幕B)

  • 当我通过点击屏幕上的一个回浏览器按钮,退出状态的我做了转移到状态B(屏幕B)为浏览器的URL变化

在画面A的onExit我做了检查,如果失败错误对话框打开后,点击错误对话框关闭返回失败的诺言对onExit

然而,onExit却还在继续前进,我去B屏

是否有可能阻止国家A(画面A)B国(画面B)如果事情在onExit失败?

过渡
解决方案

您可以实现你的目标,实施的 $ stateChangeStart 事件处理程序中,你可以取消该状态转移(事件preventDefault(); )。在需要的时候

下面下面就是一个复选框模拟禁用过渡的条件的例子。在这种情况下,对状态变化(包括state.go和导航),它会打开一个模式要求用户接受/拒绝封锁的过渡(一些验证检查的另一个模拟):

\r
\r

VAR对myApp = angular.module('对myApp',['ui.router 'ui.bootstrap']);\r
\r
myApp.config(函数($ stateProvider,$ urlRouterProvider){\r
\r
  $ urlRouterProvider.otherwise('/ state_a');\r
\r
  $ stateProvider\r
    .STATE('state_a',{\r
      网址:'/ state_a',\r
      templateUrl:stateA.html',\r
      的OnEnter:功能(){\r
        的console.log(的OnEnter stateA);\r
      },\r
      onExit:函数($ rootScope,$州){\r
        的console.log(onExit stateA:+ $ rootScope.chk.transitionEnable);\r
        \r
      },\r
      控制器:函数($范围,$州){\r
        $ scope.goToStateB =功能(){\r
          $ state.go(state_b);\r
        }\r
      }\r
    })\r
    .STATE('state_b',{\r
      网址:'/ state_b',\r
      templateUrl:stateB.html',\r
      的OnEnter:功能(){\r
        的console.log(的OnEnter stateB);\r
      },\r
      onExit:功能(){\r
        的console.log(onExit stateB);\r
      },\r
      控制器:函数($范围){\r
        \r
      }\r
    });\r
\r
});\r
\r
myApp.controller('mainCtrl',函数($ rootScope,$范围,$ uibModal,$州){\r
\r
  $ rootScope.chk = {};\r
  $ rootScope.chk.transitionEnable =真;\r
  \r
  $ rootScope。在$('$ stateChangeStart',\r
    功能(事件,toState,toParams,fromState,fromParams,期权){\r
      如果(!$ rootScope.chk.transitionEnable){\r
        。事件preventDefault();\r
        $ scope.toState = toState;\r
        $ scope.open();\r
      }其他{\r
        的console.log($ stateChangeStart:+ toState.name);\r
      }\r
  })\r
  \r
  $ scope.open =功能(){\r
\r
    VAR modalInstance = $ uibModal.open({\r
      动画:$ scope.animationsEnabled,\r
      templateUrl:myModal.html',\r
      适用范围:$范围,\r
      控制器:函数($ uibModalInstance,$范围){\r
          $ scope.ok =功能(){\r
            $ uibModalInstance.close('OK');\r
          };\r
        \r
          $ scope.cancel =功能(){\r
            $ uibModalInstance.dismiss('取消');\r
          };\r
      },\r
      大小:SM\r
    });\r
\r
    modalInstance.result.then(函数(值){\r
      console.info('模态关闭:'+值);\r
        \r
    },函数(){\r
      console.info('模态驳回');\r
      $ rootScope.chk.transitionEnable =真;\r
      $ state.go($ scope.toState.name);\r
    });\r
  };\r
\r
});

\r

<!DOCTYPE HTML>\r
< HTML和GT;\r
\r
< HEAD>\r
  <链接HREF =// netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css的rel =stylesheet属性>\r
  &LT;脚本的src =// ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.js\"></script>\r
  &LT;脚本的src =// ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular-animate.js\"></script>\r
  &LT;脚本的src =// angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.1.1.js\"></script>\r
  &LT;脚本src=\"//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.17/angular-ui-router.min.js\"></script>\r
  &所述; SCRIPT SRC =app.js&GT;&下; /脚本&GT;\r
&LT; /头&GT;\r
\r
&LT;机身NG-应用=对myAppNG控制器=mainCtrl&GT;\r
\r
  &LT;导航类=导航栏导航栏逆角色=导航&GT;\r
    &LT; D​​IV CLASS =导航栏头&GT;\r
      &LT;一类=Navbar的品牌UI-SREF =#&GT; AngularUI路由器&LT; / A&GT;\r
    &LT; / DIV&GT;\r
    &LT; UL类=NAV导航栏,导航&GT;\r
      &LT;立GT;&LT;一个UI的SREF =state_a&GT;州A&LT; / A&GT;&LT; /李&GT;\r
      &LT;立GT;&LT;一个UI的SREF =state_b&GT;状态B&LT; / A&GT;&LT; /李&GT;\r
    &LT; / UL&GT;\r
  &LT; / NAV&GT;\r
\r
  &LT; D​​IV CLASS =容器&GT;\r
    &LT;格UI的视图&gt;&LT; / DIV&GT;\r
  &LT; / DIV&GT;\r
\r
  &LT;脚本类型=文/ NG-模板ID =myModal.html&GT;\r
    &LT; D​​IV CLASS =模头&GT;\r
      &LT; H3类=模式标题&GT;标题&LT; / H3 GT&;\r
    &LT; / DIV&GT;\r
    &LT; D​​IV CLASS =模体&GT;\r
      过渡至&lt; B个{{toState.name}}&下; / B个被禁用,接受或忽略?\r
    &LT; / DIV&GT;\r
    &LT; D​​IV CLASS =模式躯&GT;\r
      &LT;按钮类=BTN BTN-主要型=按钮NG点击=OK()&GT;&接受LT; /按钮&GT;\r
      &LT;按钮类=BTN BTN-警告型=按钮NG点击=取消()&GT;忽略并LT; /按钮&GT;\r
    &LT; / DIV&GT;\r
  &LT; / SCRIPT&GT;\r
 \r
  &LT;脚本类型=文/ NG-模板ID =stateA.html&GT;\r
  &LT; D​​IV CLASS =超大屏幕文本中心&GT;\r
    &LT; H1&GT;州A&LT; / H1&GT;\r
    &所述p为H.;实施例&下; / P&GT;\r
    \r
    &所述;类别=BTN BTN-主纳克点击=goToStateB()&GT;转到状态B下; / A&GT;\r
    &LT;一类=BTN BTN-危险&GT;什么都不做...&LT; / A&GT;\r
  &LT; / DIV&GT;\r
  &LT; D​​IV CLASS =复选框&GT;\r
    &LT;标签&gt;\r
      &LT;输入类型=复选框NG模型=chk.transitionEnable&GT;启用过渡\r
    &LT; /标签&gt;\r
    &LT; pre&GT; chk.transitionEnable = {{chk.transitionEnable}}&LT; / pre&GT;\r
  &LT; / DIV&GT;\r
  &LT; / SCRIPT&GT;\r
  \r
  &LT;脚本类型=文/ NG-模板ID =stateB.html&GT;\r
&LT; D​​IV CLASS =超大屏幕文本中心&GT;\r
    &LT; H1&GT;状态B&LT; / H1&GT;\r
    &LT; P&gt;在页...&LT; / P&GT;\r
&LT; / DIV&GT;\r
\r
&LT; D​​IV CLASS =容器&GT;\r
    喇嘛喇嘛\r
  &LT; D​​IV CLASS =复选框&GT;\r
    &LT;标签&gt;\r
      &LT;输入类型=复选框NG模型=chk.transitionEnable&GT;启用过渡\r
    &LT; /标签&gt;\r
    &LT; pre&GT; chk.transitionEnable = {{chk.transitionEnable}}&LT; / pre&GT;\r
  &LT; / DIV&GT;\r
&LT; / DIV&GT;\r
  &LT; / SCRIPT&GT;\r
\r
&LT; /身体GT;\r
\r
&LT; / HTML&GT;

\r

\r
\r

I have two states, A and B.

  • When I exit state A by clicking on a close button I do a transition to screen A using $state.go to state B (screen B)
  • When I exit state A by clicking on the back browser button on screen A I do a transition to state B (screen B) as the browser URL changes

In the onExit of screen A I do a check and if this fails an Error Dialog opens, clicking Close on the error dialog returns a failed promise to the onExit

However the onExit still goes ahead and I go to screen B

Is it possible to stop the transition from State A (Screen A) to State B (Screen B) if something fails in the onExit?

解决方案

You can achieve your goal implementing a $stateChangeStart event handler in which you can cancel the state transition (event.preventDefault();) when needed.

Here below is an example where a checkBox simulate a condition of transition disabled. In this case on state change (both state.go and navigation) it opens a modal asking the user to accept/reject the transition blocked (another simulation of some validation check):

var myApp = angular.module('myApp', ['ui.router','ui.bootstrap']);

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

  $urlRouterProvider.otherwise('/state_a');

  $stateProvider
    .state('state_a', {
      url: '/state_a',
      templateUrl: 'stateA.html',
      onEnter: function() {
        console.log("onEnter stateA");
      },
      onExit: function($rootScope, $state) {
        console.log("onExit stateA: "+$rootScope.chk.transitionEnable);
        
      },
      controller: function($scope, $state) {
        $scope.goToStateB = function() {
          $state.go("state_b");
        }
      }
    })
    .state('state_b', {
      url: '/state_b',
      templateUrl: 'stateB.html',
      onEnter: function() {
        console.log("onEnter stateB");
      },
      onExit: function() {
        console.log("onExit stateB");
      },
      controller: function($scope) {
        
      }
    });

});

myApp.controller('mainCtrl', function($rootScope, $scope, $uibModal, $state) {

  $rootScope.chk = {};
  $rootScope.chk.transitionEnable = true;
  
  $rootScope.$on('$stateChangeStart',
    function(event, toState, toParams, fromState, fromParams, options) {
      if (!$rootScope.chk.transitionEnable) {
        event.preventDefault();
        $scope.toState = toState;
        $scope.open();
      } else {
        console.log("$stateChangeStart: "+toState.name);
      }
  })
  
  $scope.open = function () {

    var modalInstance = $uibModal.open({
      animation: $scope.animationsEnabled,
      templateUrl: 'myModal.html',
      scope: $scope,
      controller: function($uibModalInstance, $scope) {
          $scope.ok = function () {
            $uibModalInstance.close('ok');
          };
        
          $scope.cancel = function () {
            $uibModalInstance.dismiss('cancel');
          };
      },
      size: 'sm'
    });

    modalInstance.result.then(function (value) {
      console.info('Modal closed: ' + value);
        
    }, function () {
      console.info('Modal dismissed');
      $rootScope.chk.transitionEnable = true;
      $state.go($scope.toState.name);
    });
  };

});

<!DOCTYPE html>
<html>

<head>
  <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular-animate.js"></script>
  <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.1.1.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.17/angular-ui-router.min.js"></script>
  <script src="app.js"></script>
</head>

<body ng-app="myApp" ng-controller="mainCtrl">

  <nav class="navbar navbar-inverse" role="navigation">
    <div class="navbar-header">
      <a class="navbar-brand" ui-sref="#">AngularUI Router</a>
    </div>
    <ul class="nav navbar-nav">
      <li><a ui-sref="state_a">State A</a></li>
      <li><a ui-sref="state_b">State B</a></li>
    </ul>
  </nav>

  <div class="container">
    <div ui-view></div>
  </div>

  <script type="text/ng-template" id="myModal.html">
    <div class="modal-header">
      <h3 class="modal-title">Title</h3>
    </div>
    <div class="modal-body">
      Transition to <b>{{toState.name}}</b> is disabled, accept or ignore?
    </div>
    <div class="modal-footer">
      <button class="btn btn-primary" type="button" ng-click="ok()">Accept</button>
      <button class="btn btn-warning" type="button" ng-click="cancel()">Ignore</button>
    </div>
  </script>
 
  <script type="text/ng-template" id="stateA.html">
  <div class="jumbotron text-center">
    <h1>state A</h1>
    <p>Example</p>
    
    <a class="btn btn-primary" ng-click="goToStateB()">Goto State B</a>
    <a class="btn btn-danger">Do nothing...</a>
  </div>
  <div class="checkbox">
    <label>
      <input type="checkbox" ng-model="chk.transitionEnable"> Enable transition
    </label>
    <pre>chk.transitionEnable = {{chk.transitionEnable}}</pre>
  </div>
  </script>
  
  <script type="text/ng-template" id="stateB.html">
<div class="jumbotron text-center">
    <h1>state B</h1>
    <p>The page... </p>
</div>

<div class="container">
    Bla bla
  <div class="checkbox">
    <label>
      <input type="checkbox" ng-model="chk.transitionEnable"> Enable transition
    </label>
    <pre>chk.transitionEnable = {{chk.transitionEnable}}</pre>
  </div>
</div>
  </script>

</body>

</html>

这篇关于我可以停止在onExit过渡到下一个状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆