Problems with multilevel ion-nav-view

    0
    down vote

    favorite

I am trying to implement 3 level nesting using ion-nav-view. However, I am not able to implement in completely.

The first problem is that when I click on the ‘Insights Type 1’ or
’Insights Type 2’ button, I don’t want the entire page to change but
only the inner ‘ion-nav-view’ part. I don’t need the sliding effect as
well.

Second, I want the variable passed in the URL
’#/tab/facts2/insights/:1’, (which is written as a constant 1 here) to
be used by the controller of state ‘tabs.facts2’ to initialize ‘code’
variable. I need to initialized some common data for the child states
using this variable in the parent controller itself.
I know it is possible if I use ‘#/tab/facts2/:1’ as my URL but that will
not take me directly to the desired state, which is
’tabs.facts2.insights1’.

here is the link to my complete code: http://codepen.io/anon/pen/bdYGJm

Hello @anmolarora

I’m not sure I got your explanation right. Specially the bit about what you want to do with the url parameters.

Anyway… First, let’s get navigation working.

In your templates/facts.html used by the tabs.facts $state you have this

<a class="button icon icon-right ion-chevron-right" href="#/tab/facts2/insights">More Facts</a>

and you have two states at the same level of the hierarchy declared with the same url

    .state('tabs.facts2.insights1', {
      url: "/insights",
      views: {
        'insights-tab': {
          templateUrl: "templates/insights1.html"
        }
      }
    })
  .state('tabs.facts2.insights2', {
      url: "/insights",
      views: {
        'insights-tab': {
          templateUrl: "templates/insights2.html"
        }
      }
    })

And when you navigate to that URL, only ```tabs.facts2.insights1` is being hit.

So, giving each state a different URL, and fixing the respective hrefs in your code the navigation works.

HINT: This is where ui-sref shows its worth. You can wire your navigation with states, not with urls.

To disable the transition, just add nav-transition="none" to your a element as detailed here http://ionicframework.com/docs/api/directive/navTransition/ and you get

 <a class="button" nav-transition="none" href="#/tab/facts2/insights1"> Insights Type 1</a>

So, your navigation should now be sorted out.


Please elaborate on what you want to do with the parameters. This is the relevant ui-router documentation:

For sharing data between a state and its children, this is what you want to read:

Hi @nuba

First of all, thanks a lot for the serious effort that you’ve put for understanding the code and replying.
Basically, I want to put the states - insights1 and insights2 at the same level of hierarchy and when I click on the ‘More Facts’, I want to go to the page with insights1 view. From there, I want both the views to be accessible under the same parent view.

In short, I need a view with segmented controls. Something like this -

Regarding the parameter thing.

Based on your response, I have made some changes in the code and here is the new one

I want to utilize the parameter ‘ID’ in ‘tabs.facts2’ state to initialize some variables that are accessible in both the child states - ‘tabs.facts2.insights1’ & ‘tabs.facts2.insights2’.

Apart from this I am facing a new problem while navigating between the 2 child states. Adding nav-transition=“none” helped to remove the animation but while I navigate I get the back button pointing to the previous state which is not desired. I want the back button to point to the parent state where I originally came from, that is - ‘tabs.facts’.
Please help. Thanks in advance.

This is how I’d go about using the state’s resolve to use the state’s parameters to prepare some data for the state’s descendants. http://codepen.io/nuba/full/QbOMEP notice I’ve created a dummy service so you can see how it works.

About animations and transitions: sorry, I’m not the best person to help with that, I’ve started with Ionic just recently and haven’t looked at that part of the framework yet.

Also, there’s something broken with the innermost 's height in that codepen, I haven’t looked at it.

Thanks @nuba
That was really helpful and fixed some major problems in my code. But even after implementing it the same way as you did, I am still facing some problems.
If I use ion-nav-view, the child views are not loading however using ui-view solves the problem partially but I don’t want to use that.

The previous code was quite messed up. So I’ve written a clean one and request you to check the code here:

basically, I want the list of projects to show up as the parent screen and then the tasks of each project as the child screen with 2 sub views- one for completed tasks and other one for all tasks. I want to shuffle between these 2 subviews without changing the back button, which should take me to the projects screen.

I understand the value of your time which you’ve been taking out to help me solving this problem and will be really grateful if you can do it one more time.
Thanks.

I forked your codepen and got it to work with the states you have there. Notice I barely touched your js, just fixed the templates http://codepen.io/nuba/pen/LVOBKR

Now, the navigation flow you want is not how it works by default with Ionic and ion-nav-view… So you’d have to hack something around $ionicHistory, and that is probably not a good idea if you’re still learning the ropes around Ionic and ui-router! :wink:

So, I looked at what you wanted to achieve, went a step back, ditched the nested states and wrote a vanilla angular solution: http://codepen.io/nuba/pen/RPjYoQ

Now, instead of dealing with complex navigation and history issues, transitions, etc. we have just a boolean flag driving what’s being shown. No nested states required.

Hope it’ll get you going! Good luck!

Thanks again :wink:
The code works well now

I couldn’t just understand how the ng-if thinking is working here. Can you please explain that?

Well. Here we’re setting our boolean flag: showAll.

<a class="button" ng-click="showAll = true" ng-class="{'button-positive': showAll}">All</a>
<a class="button" ng-click="showAll = false" ng-class="{'button-positive': !showAll}">Completed</a>

Check the controller and you’ll see it was initialized there with the true value.

Here we’re using the fact that ng-repeat (priority 1000) is compiled before ng-if(priority 600). That means there will be a <div> element for each task and then each ng-if in those <div>s will be processed to determine if it should be included in the page.

<div class=item ng-repeat="task in myData.Tasks" ng-if="showAll || task.completed == 1">
  <h3>{{ task.TaskName }}</h3>
</div>

When showAll is true, all tasks’s div will added to the page.
When showAll is false, only the completed tasks will be added to the page.

Well that’s the best explanation I could get. And the solution seems perfect too - Nice and Clean :thumbsup:

Thanks for your time and support @nuba. :slight_smile: