ionic-team / ionic-team/ionic-framework
Wrong navigation direction/animation with Angular router after CanDeactivate stops navigation
- 主要言語
- TypeScript
- スター
- 52.7k
- フォーク
- 13.3k
- 平均マージ
- 1日 15時間
- マージ済み PR(30日)
- 51
説明
# Bug Report
**Ionic version:**
[x] **4.x**
**Current behavior:**
Using the Angular router to forward navigate after a `CanDeactivate` route guard has stopped a `NavController.back` from taking place results in the wrong navigation animation direction and a reset Ionic push/pop stack.
**Expected behavior:**
The correct navigation animation will be used and the Ionic stack will not be reset when forward navigating with the Angular router even in the case where a `CanDeactivate` route guard has stopped a back navigation.
**Steps to reproduce:**
1. Clone the following repo: https://github.com/KevinKelchen/issue-ionic4-can-deactivate-animation
- It is the Angular sidemenu starter template with minor modifications (namely that the sidemenu items, when clicked, do different things).
2. Run `npm i`.
3. Run `ionic serve`.
4. Open Google Chrome Dev Tools.
5. In Google Chrome Dev Tools click "Toggle device toolbar" to simulate a device UI.
6. In device toolbar settings, from the device type dropdown choose "iPad Pro."
- This will make it use the `ios` mode whose navigation animation directions are more obvious to the eye (content moving left or right).
- "iPad Pro" is a large enough resolution that the sidemenu will remain visible on the screen.
7. In device toolbar settings, from the zoom level dropdown choose "100%."
- Sometimes with a smaller percentage the click areas get messed up.
8. Reload the browser to ensure that the simulated user agent will be used.
9. In the Dev Tools Elements panel, expand the nodes for the following path:
- `body > app-root > ion-app > ion-split-pane > ion-router-outlet`
- This will allow you to keep a visual on the Ionic push/pop stack as you navigate in the app.
10. Click `List (Router.navigate)` and note that the navigation direction/animation goes forward as it is using `Router.navigate`.
- You'll also see the Page get added to the Ionic stack in the Elements panel.
11. Click `Bonus (Router.navigate)` and note that the navigation direction/animation goes forward as it is using `Router.navigate`.
- You'll also see the Page get added to the Ionic stack in the Elements panel.
12. Click `Home (NavController.back)` and note that the navigation direction/animation goes back as it is using `NavController.back`.
- Since this used `NavController.back`, you will be back on the `List` screen. You'll see the `Bonus` Page was removed from the Ionic stack in the Elements panel.
13. In the Dev Tools Console, copy/paste the following statement and hit Enter/return:
- `window.disableNav = true`
- This flag will force the `CanDeactivate` Angular route guard to return `false` and prevent subsequent navigations.
14. Click `Home (NavController.back)`. The navigation will be prevented by the `CanDeactivate` route guard.
15. In the Dev Tools Console, copy/paste the following statement and hit Enter/return:
- `window.disableNav = false`
16. Click `Bonus (Router.navigate)` and note that the navigation direction/animation goes _backwards_ instead of forwards like it's supposed to.
- You'll also see all of the Pages in the Ionic stack in the Elements panel have been destroyed except for the current Page you're on (`Bonus`).
**Related code:**
See _Steps to reproduce_.
**Other information:**
Here's what I can tell about what's happening:
1. In the `NavController`, on the `NavigationStart` Angular router event [`this.guessDirection` and `this.guessAnimation` are set](https://github.com/ionic-team/ionic/blob/4d56dfe2eef0e787874fe6d7b615108f9aeca79c/angular/src/providers/nav-controller.ts#L39). These values are [used in `NavController.consumeTransition`](https://github.com/ionic-team/ionic/blob/4d56dfe2eef0e787874fe6d7b615108f9aeca79c/angular/src/providers/nav-controller.ts#L163) when `this.direction` is `auto`, or in other words, is not explicitly set to a specific direction.
- Note that it is also in `consumeTransition` that [`this.direction` is set back to the default value](https://github.com/ionic-team/ionic/blob/4d56dfe2eef0e787874fe6d7b615108f9aeca79c/angular/src/providers/nav-controller.ts#L174) of [`auto`](https://github.com/ionic-team/ionic/blob/4d56dfe2eef0e787874fe6d7b615108f9aeca79c/angular/src/providers/nav-controller.ts#L207).
2. [`NavController.back` will explicitly set the direction/animation](https://github.com/ionic-team/ionic/blob/4d56dfe2eef0e787874fe6d7b615108f9aeca79c/angular/src/providers/nav-controller.ts#L118) using `setDirection`.
3. When the `CanDeactivate` guard returns `false` and stops the navigation, the `back` direction/animation from `setDirection` do not get reverted to the default values but remain in place. This is because `consumeTransition` never happens which is where they would otherwise get reset to the default values.
4. Then upon forward navigating with the Angular router, in `consumeTransition`, `this.direction` still has a non-`auto` value of `back` and it uses that instead of `auto`/`this.guessDirection`/`this.guessAnimation`.
Perhaps after every navigation--even if it doesn't succeed--these default values can be reset. Not sure if it'd involve subscribing to certain Angular router events or if there's a better/existing "hook" to put this type of handling within the Ionic framework.
I’ve worked around the issue for now by explicitly calling `setDirection` with forward navigation values before invoking the Angular router to forward navigate. Using `NavController.navigateForward` is another option.
**Ionic info:**
```
Ionic:
ionic (Ionic CLI) : 4.6.0 (/usr/local/lib/node_modules/ionic)
Ionic Framework : @ionic/angular 4.0.1
@angular-devkit/build-angular : 0.12.4
@angular-devkit/schematics : 7.2.4
@angular/cli : 7.2.4
@ionic/angular-toolkit : 1.4.0
System:
NodeJS : v10.13.0 (/usr/local/bin/node)
npm : 6.4.1
OS : macOS Mojave
```
コントリビューションガイド
評価
この issue はまだ評価されていません。