Search code examples
androidsteroidsappgyversupersonic

AppGyver Supersonic navigating between Views and creating duplicates


I'm using AppGyver Steroids and Supersonic to build an app and I'm having some issues navigating between views programmatically.

Based on the docs, you navigate between views like this:

var view_obj = new supersonic.ui.View("main#index");
supersonic.ui.layers.push(view_obj);

However, when I inspect things via the Chrome DevTools, it appears that a second duplicate view is created i.e. If I navigate away from the index page and then navigate back, I now have two index pages, instead of what [I think] should be one. It also doesn't close the previous view I was on.

How can I prevent this from happening and simply move to the existing view, instead of duplicating views? How do I close a view after I have navigated away from it?

Thanks.


Solution

  • The problem you're encountering is that you're creating a new supersonic.ui.View("main#index") every time you navigate. On top of this, I think you want to return to the same view when you navigate back to a view for the second time, i.e. you want the view to remain in memory even if it has been removed from the navigation stack with pop() (rather than pushing a new instance of that view). For this, you need to preload or "start()" the view, as described in the docs here.

    I implemented my own helper function to make this easier; here is my code:

    start = function(dest, isModal) {
      var viewId=dest,
          view=new supersonic.ui.View({
            location: dest,
            id: viewId
          });
      view.isStarted().then(function(started) {
        if (started) {
          if (isModal) {supersonic.ui.modal.show(view);}
          else {supersonic.ui.layers.push(view);}
        } else {
          // Start Spinner
          supersonic.ui.views.start(view).then(function() {
            if (isModal) {supersonic.ui.modal.show(view);}
            else {supersonic.ui.layers.push(view);}
            // Stop Spinner
          }, function(error) {
            // Stop Spinner
            A.error(error);
          });
        }
      });
    };

    Use it like start('module#view');. As a bonus, you can pass true as the second argument and it gets pushed as a modal instead.

    It checks if you've already started a view - if so, it just pushes that view back onto the stack. If not, it start()s (i.e. preloads) it, then pushes it. This ensures that the view stays in memory (with any user input that has been modified) even when you pop() it from the stack.

    You have to imagine that the layer stack is actually a stack in the Computer Science sense. You can only add and remove views at the top of the stack. The consequence of this is that complex navigations such as A > B > C > D > B are difficult/hacky to do (in this case, you'd have to pop() D and C in succession to get back to B).

    Views will close if you pop() them, as long as you didn't start() them. If you did, and you pop() them, they remain in memory. To kill that view, you have to call stop() on it, as described in the docs I linked above.