Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nav-clear in sidemenu breaks navigation #1043

Closed
michaelkrog opened this issue Apr 3, 2014 · 15 comments
Closed

nav-clear in sidemenu breaks navigation #1043

michaelkrog opened this issue Apr 3, 2014 · 15 comments

Comments

@michaelkrog
Copy link

If i have sidemenu (abstract state: menu), a page (state: menu.page) and a subpage (state: menu.page.subpage) and I use nav-clear on links in the sidemenu to disable animations when the links are clicked in the sidemenu, then subsequent navigation seems to break.

The way I see it is:

  • animations between views no longer happen.
  • back buttons disappear.

I made a codepen here: http://codepen.io/anon/pen/HLaDu/

Try to go to subpage and then back. It works fine - back and forth several times. But as soon as I open the sidemenu and click the link to go to close the menu again, then it is broken.

If I remove nav-clear from the link in the sidemenu, then things works fine - but leaves me with the animation-between-views problem which nav-clear was supposed to fix.

(Using beta 1)

@ajoslin ajoslin self-assigned this Apr 4, 2014
@ajoslin
Copy link
Contributor

ajoslin commented Apr 4, 2014

The problem in this specific codepen is that the href link given by your navClear element doesn't go to an actual page. Therefore, the next view after that takes the navClear's viewOptions.

To put it more simply .. navClear is trying to say 'hey next page, don't animate or show a back button'. Then you click it, and it tells that to .. no page! Because the href doesn't go anywhere.

So then the page after that gets no view and back button.

@ajoslin ajoslin closed this as completed Apr 4, 2014
@michaelkrog
Copy link
Author

Yep, I had a wrong path set for the href in the sidemenu in this codepen.

But if I change it to the correct path(#/menu/page) the problem still persists?
(I have changed the codepen to have the correct path)

@ajoslin ajoslin reopened this Apr 4, 2014
@ajoslin
Copy link
Contributor

ajoslin commented Apr 4, 2014

Hm.. it's still the same problem internally, the page isn't actually changing because we're going to the link we're already on.

However, that is not what is expected from the directive and should be fixed. Will leave open, thanks.

@michaelkrog
Copy link
Author

I'm pretty new to Ionic but never the less - here's my 5 cents. :)

This is the current directive:

.directive('navClear', ['$ionicViewService', function($ionicViewService) {
  return {
    restrict: 'AC',
    link: function($scope, $element, $attr) {
      $element.bind('click', function(){
        $ionicViewService.nextViewOptions({
          disableAnimate: true,
          disableBack: true
        });
      });
    }
  };
}]);

I'm thinking that either you wan't nav-clear or you don't - for the whole ion-side-menu.

So maybe this could work: In case nav-clear is set on ion-side-menu it could wait for $stateChangeStart to be emitted (while menu is open) before it calls $ionicViewService.nextViewOptions()? This way it never never disable animation and backbutton unless the state is actually changing.

If would then be something like this:

.directive('navClear', ['$ionicViewService', function($ionicViewService) {
  return {
    restrict: 'AC',
    link: function($scope, $element, $attr) {
      var disableOptions = {
          disableAnimate: true,
          disableBack: true
        });

      // Semi-Pseudo START
      if(inSidemenu) {
          $rootScope.$on('$stateChangeStart',  function(event, toState, toParams, fromState, fromParams){ 
              if(menuOpen) {
                  $ionicViewService.nextViewOptions(disableOptions);
              }
          }
      } else {
      // Semi-Pseudo END
        $element.bind('click', function(){
          $ionicViewService.nextViewOptions(disableOptions);
        });
      }
    }
  };
}]);

@ajoslin
Copy link
Contributor

ajoslin commented Apr 4, 2014

Good research @michaelkrog!

But what if the navClear is clicked, the $stateChangeStart is listened for, and then no state change happens immediately (same href problem again)? Then the next state change actually ends up happening a lot later, and we have the same problem. Or what if the side menu is open and someone changes state programatically?

Possible solution off the top of my head: force nav-clear to say which state it is targetting, via href, ui-sref, or the nav-clear attribute itself. Then, set the navViewOptions only if that state is reachable and is not the current state on click.

@michaelkrog
Copy link
Author

Thx @ajoslin

Well..I see 2 outcomes from clicking a link in the sidemenu:
1) User chooses another view than the current view and therefore state changes.
2) User chooses the same view as the current view and therefore state does not change.

If we never add the disablement when no. 2 happens then I can't see that it will do any harm later on.

But using href or ui-sref seems better(I like that more than via nav-clear). This way it keeps its general aspect and is does not need to know anything about its surroundings other than the target of the currently clicked link.

@michaelkrog
Copy link
Author

I can confirm that changing the navClear-directive to keep an eye on ui-sref indeed can work. I changed the linker in the directive to this:

link: function ($scope, $element, $attr) {
    var uiSref = $attr.uiSref;
    $element.bind('click', function () {
        if(!$state.is(uiSref)) {
            $ionicViewService.nextViewOptions({
                disableAnimate: true,
                disableBack: true
            });
        }
    });
}

This fixes my issue but is of course not a full resolution. This fix currently requires:

  1. That ui-sref is used instead of href.
  2. That the state set in ui-sref is valid (invalid ui-sref may cause the same issue with disablement being used for later view changes.)

@ajoslin
Copy link
Contributor

ajoslin commented Apr 7, 2014

After some thought, I think really the most reliable way to get around the problems while still using our current infrastructure is a setTimeout.

The setTimeout still has a few edge cases that are problematic, but it is the best I could think of without having to get really complicated.

var unregisterListener;
function listenForStateChange() {
  unregisterListener = $scope.$on('$stateChangeStart', function() {
     $ionicViewService.nextViewOptions({
       disableAnimate: true,
       disableBack: true
     });
  });
  setTimeout(unregisterListener, 300);
}
$element.on('click', listenForStateChange);

Some future work needs to be done on a proper solution, though..

And this will still break if the state change fails.

@ajoslin ajoslin closed this as completed in 4dffc5f Apr 7, 2014
@karvapallo
Copy link

I think this issue has been re-introduced in ionic 1.0.0 or 1.0.1 (updated from RC5) in a way.

I have a situation where, in the left navigation I have a href to #/posts, which is fine. So when on that page and I click this #/posts href to 're-open' the page I'm already on, and then on that page, I click to the comments section, which is #/posts/:postId/comments, this new comments page opens up as the root page (no animation and hamburger icon on the left upper hand corner.)

But if I click to a e.g. user's page #/users/:userId this does not happen. So somehow ionic sees the #/posts/:postId/comments page as being the same page we are already on (i.e. #/posts) probably due to them both beginning with #/posts.

An easy workaround is of course, to use a different URL for the comments, but it really doesn't seem like very elegant solution.

EDIT: Correction, it doesn't matter what the next URL is, it will still clear the history stack and make the next page root. Sorry for the confusion.

@SimonRiis
Copy link

I too have this problem with nav-clear.
I have a list of events, if i click one it navigates to it, i then click on the menu "Burger" and it opens the side menu, i click on events and it again shows me a list of events if i click one of these events the backbutton is removed and i can only open the side menu not go back.

@violet7
Copy link

violet7 commented Aug 2, 2015

+1

@mhartington
Copy link
Contributor

This is fixed in the nightly builds.

http://codepen.io/mhartington/pen/KpbQVd

@karvapallo
Copy link

Oh great, I'll check that out. Thank you!

@violet7
Copy link

violet7 commented Aug 2, 2015

Thank you.

@fengliliu
Copy link

有点牛逼

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Sep 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants