NativeScript / nativescript-angular

Integrating NativeScript with Angular
http://docs.nativescript.org/angular/tutorial/ng-chapter-0
Apache License 2.0
1.21k stars 248 forks source link

Named outlets in BottomNavigation #2079

Open armpogart opened 4 years ago

armpogart commented 4 years ago

Environment Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

Describe the bug

Module children navigation for named outlets doesn't work in BottomNavigation.

To Reproduce

I have prepared 2 Playgrounds that show the issue:

The only difference between these version is in home.component.html. The first version has

<StackLayout>
    <Label text="HomeComponent"></Label>
    <Label text="testTab outlet:"></Label>
    <router-outlet name="testTab"></router-outlet>
    <Label text="anotherTab outlet:"></Label>
    <router-outlet name="anotherTab"></router-outlet>
</StackLayout>

and the second version has:

<BottomNavigation>

    <!-- The bottom tab UI is created via TabStrip (the containier) and TabStripItem (for each tab)-->
    <TabStrip>
        <TabStripItem class="navigation__item">
            <Label text="Test"></Label>
        </TabStripItem>
        <TabStripItem class="navigation__item">
            <Label text="Another"></Label>
        </TabStripItem>
    </TabStrip>

    <!-- The number of TabContentItem components should corespond to the number of TabStripItem components -->
    <TabContentItem>
        <page-router-outlet name="testTab"></page-router-outlet>
    </TabContentItem>
    <TabContentItem>
        <page-router-outlet name="anotherTab"></page-router-outlet>
    </TabContentItem>

</BottomNavigation>

The home.routing.module has the following routes:

const routes: Routes = [
    {
        path: "",
        component: HomeComponent,
        children: [
            {
                path: '',
                component: TestComponent,
                outlet: 'testTab',
            },
            {
                path: '',
                component: AnotherComponent,
                outlet: 'anotherTab',
            },
        ]
    }
];

The first version works correctly (per angular logic) and loads the components for outlets. The second version doesn't load the components for outlets.

Expected behavior I expect the second version work without any issue (be loading components to their outlets). I know that I can navigate outlets programmatically and use custom paths for them, but I don't see any reason why this approach must not work.

Pandishpan commented 4 years ago

@armpogart nothing it's wrong with navigation (except for this issue 👎 https://github.com/NativeScript/nativescript-angular/issues/2075) your example is wrong...

I fixed your example take a look in here https://play.nativescript.org/?template=play-ng&id=5dBs7Y (I amended app-routing.module.ts & home-routing.module.ts)

I recommend you to read these blog posts: https://www.nativescript.org/blog/implementing-a-login-for-nativescript-apps-with-tab-based-navigation https://www.nativescript.org/blog/using-nested-router-outlets-with-nativescript-and-angular

tsonevn commented 4 years ago

Hi @armpogart, Were you able to solve your case by following the example provided by @Pandishpan? If so, we can close this issue.

armpogart commented 4 years ago

@Pandishpan First of all you haven't fixed my example, you've just proposed a workaround which is utterly wrong as it breaks the purpose of angular modules and encapsulation. AppModule and it's routing module doesn't have to know the routing logic of HomeModule. I have read the articles you mentioned and many more and none of them gives the answer to my bug report (issue). If you just want a workaround, the correct way would be following: version 5. This is the right workaround, as routing logic remains in the module. But as I stated these are all just workarounds and not fixes.

@tsonevn No, I have reported a bug with clear example, just have a look at 2 playground examples which differ just in home.component.html and I still don't see any reason why the one with BottomNavigation doesn't work. I still think there is something wrong with BottomNavigation. @Pandishpan just proposed a workaround which I'm aware of. I have used similar workaround in my own project, but I think that there is an issue which needs to be fixed.

Pandishpan commented 4 years ago

@Pandishpan First of all you haven't fixed my example, you've just proposed a workaround which is utterly wrong as it breaks the purpose of angular modules and encapsulation. AppModule and it's routing module doesn't have to know the routing logic of HomeModule. I have read the articles you mentioned and many more and none of them gives the answer to my bug report (issue). If you just want a workaround, the correct way would be following: version 5. This is the right workaround, as routing logic remains in the module. But as I stated these are all just workarounds and not fixes.

@armpogart First, I was just trying to be helpful.

I'm glad that you are using the ngOnInit hook, that's the real-life usage that I'm also using. I used the route path to simplify the example.

Something must trigger loading the outlets, options:

The reason for that, sometimes you don't want to load the outlets when you first open the app (performance reasons) This is not a workaround, is the documented way to use the bottom-navigation component.

armpogart commented 4 years ago

@Pandishpan Thanks for your quick reply to my issue and your proposed workaround.

Something must trigger loading the outlets, options:

  • using the ngOnInit of home component
  • the events from bottom-navigation (selectedIndexChanged)
  • TabStrip Events (itemTap)

Yeah, I agree that something must trigger the outlets and I have clearly showed with the first example (the one without BottomNavigation, but again without outlets that routing is enough to trigger the loading of the outlets. If I didn't want that, I would have another routes and not the default empty routes for outlets.

The reason for that, sometimes you don't want to load the outlets when you first open the app (performance reasons) This is not a workaround, is the documented way to use the bottom-navigation component.

Again if I didn't want to load the outlets I would have different routing setup. I have checked all the documentation and I don't see anywhere that this behavior is documented, so please refer to the official documentation when saying that (if you mean the articles, they are outdated, in terms that they are not for the new components, and they use the old TabView which had many problems and that's the reason why the new components were introduced in the first place. So I'm for better components with the right behaviour and against workarounds). If the team officially admits the problem and issue remains open, I'm for documenting workarounds officially, but not for proposing workarounds instead of fixing issues. The latest project I have released to the mobile stores had several such workarounds which are not good for any project, they are just temporary solutions to the problem.

Furthermore I don't see anywhere in the material guidelines requirement for the Bottom Navigation to be lazy loaded or not, so it's up to developer to decide. The only requirements as per spec are about behavior differences on platforms and I'm not even sure whether nativescript correctly implements that spec.

NickIliev commented 4 years ago

@armpogart you could use router-outlet for the lateral navigation (BottomNavigaiton) - see this modified Playground demo.

armpogart commented 4 years ago

@NickIliev Yeah, but it would be just a workaround, and in my opinion it would be the worst one, as it breaks the whole purpose of page-router-outlet usage instead of router-outlet (it breaks mobile navigation pattern, such as navigation transitions, view state preservation and etc.). Please take into account that it is just simplified example, and in real world each tab loads its' own module with its' multi-level routing.

I still don't see a reason why my routing configuration must work in version 1 and not version 2.

Angusoft-India commented 4 years ago

Hi All, Is there any workaround or guide to use it correctly? Any help will be much appreciated. So far I spent two days on this issue with the page-router-outlet Please... Thanks in advance.

Angusoft-India commented 4 years ago

@armpogart

While using the page-router-outlet or router-outlet don't keep the parent path empty. Just try changing from path: "", component: HomeComponent,

to

path: "default", component: HomeComponent, It's working for me. Thanks

juniorschen commented 3 years ago

Any real solutions to that? everything shown here are only workarounds

martijnvanschie commented 3 years ago

Well, i had this very same issue for two days trying to make a nested outlet work in a BottomNavigation. Been looking at examples and blogs and jumping around the room as i used the "exact" same structures and nothing worked.

I finally got it to work. In your original issue report you are using the BottomNavigation with a page-router-outlet (and so was I). I changed that to a router-outlet and now it works.

No clue what the exact difference is between the page-router-outlet and the router-outlet but they are used randomly it seams.

At least im happy now :)