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

Feature: Enable nesting page router outlets #1351

Open
MartoYankov opened this Issue May 29, 2018 · 33 comments

Comments

@MartoYankov
Contributor

MartoYankov commented May 29, 2018

With nativescript-angular 6.0 we will enable sibling named page-router-outlet at root level to enable the scenario with root TabView with navigations inside the tabs. This scenario is demonstrated in the template - https://github.com/NativeScript/template-tab-navigation-ng.

We would like to also support nested sibling named page-router-outlet. This will enable more scenarios with PROs that are now only possible with NG . Here are two scenarios:

  1. Having a root page-router-outlet (PRO) that initially navigates to a Login page and upon login, navigates to a TabView with nested PRO navigations:
  • PRO
    • Login
    • Tabs
      • PRO: Tab 1 Master --> Tab 1 Detail
      • PRO: Tab 2 Master --> Tab 2 Detail
  1. Having a root RadSideDrawer that can switch between regular pages and TabView with nested PRO navigations:
  • RadSideDrawer
    • PRO
      • Page 1 Master --> Page 2 Detail
      • Tabs
        • PRO: Tab 1 Master --> Tab 1 Detail
        • PRO: Tab 2 Master --> Tab 2 Detail

@MartoYankov MartoYankov added the feature label May 29, 2018

@YvesCandel

This comment has been minimized.

Show comment
Hide comment
@YvesCandel

YvesCandel Jun 28, 2018

Any estimation on how complicated this feature is?

YvesCandel commented Jun 28, 2018

Any estimation on how complicated this feature is?

@manojdcoder

This comment has been minimized.

Show comment
Hide comment
@manojdcoder

manojdcoder Jul 6, 2018

@NickIliev / @vakrilov / @sis0k0 Are we depended on Angular to fix any issues on their end to complete this feature? Just curious, as I'm aware that there are few issues with Angular's router when nesting named outlets.

manojdcoder commented Jul 6, 2018

@NickIliev / @vakrilov / @sis0k0 Are we depended on Angular to fix any issues on their end to complete this feature? Just curious, as I'm aware that there are few issues with Angular's router when nesting named outlets.

@Bolhy10

This comment has been minimized.

Show comment
Hide comment
@Bolhy10

Bolhy10 commented Jul 19, 2018

@IAMtheIAM

This comment has been minimized.

Show comment
Hide comment
@IAMtheIAM

IAMtheIAM Jul 22, 2018

This is a greatly desired feature. In fact it is not desired, it is fundamentally necessary to create any kind of functional business application, most of which require some form of authentication/authorization through login before accessing the application.

In order to use NativeScript on the job, this feature is required.

IAMtheIAM commented Jul 22, 2018

This is a greatly desired feature. In fact it is not desired, it is fundamentally necessary to create any kind of functional business application, most of which require some form of authentication/authorization through login before accessing the application.

In order to use NativeScript on the job, this feature is required.

@NickIliev NickIliev added the planned label Jul 24, 2018

@NickIliev NickIliev added this to the next milestone Jul 24, 2018

@NickIliev

This comment has been minimized.

Show comment
Hide comment
@NickIliev

NickIliev Jul 24, 2018

Member

@IAMtheIAM @Bolhy10 @manojdcoder @YvesCandel thank you guys for your feedback. Indeed, we are aware that this feature is highly desirable and we are planning it for the next release of nativescript-angular. We will post all related updates here.

Member

NickIliev commented Jul 24, 2018

@IAMtheIAM @Bolhy10 @manojdcoder @YvesCandel thank you guys for your feedback. Indeed, we are aware that this feature is highly desirable and we are planning it for the next release of nativescript-angular. We will post all related updates here.

@IAMtheIAM

This comment has been minimized.

Show comment
Hide comment
@IAMtheIAM

IAMtheIAM Jul 24, 2018

@NickIliev That's great news! Thanks for the update. When the feature is available, I wonder if it is more appropriate to use an actual tabview component like being requested, or if its better to simulate a tabview and create normal page outlets using buttons styled like a tabview. What do you think?

IAMtheIAM commented Jul 24, 2018

@NickIliev That's great news! Thanks for the update. When the feature is available, I wonder if it is more appropriate to use an actual tabview component like being requested, or if its better to simulate a tabview and create normal page outlets using buttons styled like a tabview. What do you think?

@gbaldeck

This comment has been minimized.

Show comment
Hide comment
@gbaldeck

gbaldeck Jul 24, 2018

That's awesome @NickIliev. Will it be in {N} 4.2 or a later version?

gbaldeck commented Jul 24, 2018

That's awesome @NickIliev. Will it be in {N} 4.2 or a later version?

@tskweres

This comment has been minimized.

Show comment
Hide comment
@tskweres

tskweres Jul 26, 2018

Awesome! +1 for lazy loading the tab views too :)

tskweres commented Jul 26, 2018

Awesome! +1 for lazy loading the tab views too :)

@NickIliev

This comment has been minimized.

Show comment
Hide comment
@NickIliev

NickIliev Jul 26, 2018

Member

@gbaldeck the 4.2 release is a few days away and this feature is not ready and is still in the planning phase. I am sorry if I had misled anyone about the release date - the feature is planned for the 4.3 but still, in the end, it all depends on the complexity of the feature.

Member

NickIliev commented Jul 26, 2018

@gbaldeck the 4.2 release is a few days away and this feature is not ready and is still in the planning phase. I am sorry if I had misled anyone about the release date - the feature is planned for the 4.3 but still, in the end, it all depends on the complexity of the feature.

@gbaldeck

This comment has been minimized.

Show comment
Hide comment
@gbaldeck

gbaldeck Jul 26, 2018

@NickIliev In the meantime is there a workaround for having Tabs work with the RadSideDrawer?

gbaldeck commented Jul 26, 2018

@NickIliev In the meantime is there a workaround for having Tabs work with the RadSideDrawer?

@tskweres

This comment has been minimized.

Show comment
Hide comment
@tskweres

tskweres Jul 26, 2018

@gbaldeck @NickIliev I could try making a test app using just and not that has parents and children:

Login (eager)
Tabs (eager)
-- Tab one (lazy) (aux named outlet)
-- Tab Detail one
-- Tab two (lazy) (aux named outlet)
-- Tab Detail two

But - i'm curious if the page and header transitions, back button etc will still work as expected.

re: angular/angular#10981

tskweres commented Jul 26, 2018

@gbaldeck @NickIliev I could try making a test app using just and not that has parents and children:

Login (eager)
Tabs (eager)
-- Tab one (lazy) (aux named outlet)
-- Tab Detail one
-- Tab two (lazy) (aux named outlet)
-- Tab Detail two

But - i'm curious if the page and header transitions, back button etc will still work as expected.

re: angular/angular#10981

@sokolovstas

This comment has been minimized.

Show comment
Hide comment
@sokolovstas

sokolovstas Jul 29, 2018

I have found some sort of workaround for now
I have 4 outlets: 3 for tabs and one for login:

<Page backgroundSpanUnderStatusBar="true">
  <AbsoluteLayout>
    <TabView androidTabsPosition="bottom" [visibility]="!logged ? 'hidden' : 'visible'">
      <page-router-outlet
          *tabItem="{title: 'Tasks', iconSource: '~/images/list.png'}"
          name="tasksTab">
      </page-router-outlet>

      <page-router-outlet
          *tabItem="{title: 'Messages', iconSource: '~/images/speech_buble.png'}"
          name="messagesTab">
      </page-router-outlet>

      <page-router-outlet
          *tabItem="{title: 'Settings', iconSource: '~/images/settings.png'}"
          name="settingsTab">
      </page-router-outlet>
    </TabView>
    <page-router-outlet name="main" [visibility]="logged ? 'hidden' : 'visible'">
    </page-router-outlet>
  </AbsoluteLayout>
</Page>

sokolovstas commented Jul 29, 2018

I have found some sort of workaround for now
I have 4 outlets: 3 for tabs and one for login:

<Page backgroundSpanUnderStatusBar="true">
  <AbsoluteLayout>
    <TabView androidTabsPosition="bottom" [visibility]="!logged ? 'hidden' : 'visible'">
      <page-router-outlet
          *tabItem="{title: 'Tasks', iconSource: '~/images/list.png'}"
          name="tasksTab">
      </page-router-outlet>

      <page-router-outlet
          *tabItem="{title: 'Messages', iconSource: '~/images/speech_buble.png'}"
          name="messagesTab">
      </page-router-outlet>

      <page-router-outlet
          *tabItem="{title: 'Settings', iconSource: '~/images/settings.png'}"
          name="settingsTab">
      </page-router-outlet>
    </TabView>
    <page-router-outlet name="main" [visibility]="logged ? 'hidden' : 'visible'">
    </page-router-outlet>
  </AbsoluteLayout>
</Page>

@hettiger

This comment has been minimized.

Show comment
Hide comment
@hettiger

hettiger Aug 9, 2018

@MartoYankov Can you please add Lazy Loading the Tab Views to your list. I think this is also really important. Here's an issue for reference. Nested routes / routes with children / lazy loaded routes do not work with named page router outlets.

hettiger commented Aug 9, 2018

@MartoYankov Can you please add Lazy Loading the Tab Views to your list. I think this is also really important. Here's an issue for reference. Nested routes / routes with children / lazy loaded routes do not work with named page router outlets.

@sokolovstas

This comment has been minimized.

Show comment
Hide comment
@sokolovstas

sokolovstas Aug 9, 2018

I have found another workaround for my application. Just show the modal dialog with login on start.

sokolovstas commented Aug 9, 2018

I have found another workaround for my application. Just show the modal dialog with login on start.

@MartoYankov

This comment has been minimized.

Show comment
Hide comment
@MartoYankov

MartoYankov Aug 9, 2018

Contributor

@sokolovstas This is indeed a valid workaround and in fact is the suggested pattern for login with root TabView in native mobile.

@hettiger The nested routes/routes with children problems are indeed tied to this feature request. However, the problems with lazy loading named outlet routes are a separate issue and is not well handled in angular. See angular/angular#24657 .

Contributor

MartoYankov commented Aug 9, 2018

@sokolovstas This is indeed a valid workaround and in fact is the suggested pattern for login with root TabView in native mobile.

@hettiger The nested routes/routes with children problems are indeed tied to this feature request. However, the problems with lazy loading named outlet routes are a separate issue and is not well handled in angular. See angular/angular#24657 .

@hettiger

This comment has been minimized.

Show comment
Hide comment
@hettiger

hettiger Aug 10, 2018

@sokolovstas @MartoYankov

The suggested modal view workaround leads me to another problem:
Modal view navigation requires a PRO and it seems to cause issues?

A login view should support creating accounts and resetting lost passwords.
Navigation is a requirement for good UX in that case thought.

hettiger commented Aug 10, 2018

@sokolovstas @MartoYankov

The suggested modal view workaround leads me to another problem:
Modal view navigation requires a PRO and it seems to cause issues?

A login view should support creating accounts and resetting lost passwords.
Navigation is a requirement for good UX in that case thought.

@sokolovstas

This comment has been minimized.

Show comment
Hide comment
@sokolovstas

sokolovstas Aug 10, 2018

I agree that this is workaround only. For now, I have 3 modals and open one and close another on navigation.

sokolovstas commented Aug 10, 2018

I agree that this is workaround only. For now, I have 3 modals and open one and close another on navigation.

@MartoYankov

This comment has been minimized.

Show comment
Hide comment
@MartoYankov

MartoYankov Aug 10, 2018

Contributor

@hettiger @sokolovstas The navigation inside a modal with PRO should work. Can you please share the issue you experience?

Contributor

MartoYankov commented Aug 10, 2018

@hettiger @sokolovstas The navigation inside a modal with PRO should work. Can you please share the issue you experience?

@hettiger

This comment has been minimized.

Show comment
Hide comment
@hettiger

hettiger Aug 10, 2018

@MartoYankov

Then I am probably doing it wrong.

How am I supposed to register the modal routes?

Here's the active route when opening the modal:

    {
        path: "",
        redirectTo: "/(aTab:a//bTab:b//cTab:c)",
        pathMatch: "full"
    },

Children are not supported when using redirectTo.

That's what the examples suggest:

https://github.com/NativeScript/nativescript-sdk-examples-ng/blob/70675f2de9f8238418b93e961901cc31d0d42507/app/ng-ui-widgets-category/modal-page/modal-page-examples.module.ts#L24-L38

I don't see how the pieces can be put together.
My attempts so far didn't work out unfortunately.

If you tell me how to register the routes, I'll give it a shot and share a playground here if I'm still experiencing issues.

hettiger commented Aug 10, 2018

@MartoYankov

Then I am probably doing it wrong.

How am I supposed to register the modal routes?

Here's the active route when opening the modal:

    {
        path: "",
        redirectTo: "/(aTab:a//bTab:b//cTab:c)",
        pathMatch: "full"
    },

Children are not supported when using redirectTo.

That's what the examples suggest:

https://github.com/NativeScript/nativescript-sdk-examples-ng/blob/70675f2de9f8238418b93e961901cc31d0d42507/app/ng-ui-widgets-category/modal-page/modal-page-examples.module.ts#L24-L38

I don't see how the pieces can be put together.
My attempts so far didn't work out unfortunately.

If you tell me how to register the routes, I'll give it a shot and share a playground here if I'm still experiencing issues.

@MartoYankov

This comment has been minimized.

Show comment
Hide comment
@MartoYankov

MartoYankov Aug 13, 2018

Contributor

@hettiger You won't be able to open a modal page just with the router. At least we haven't figured it out yet. There is docs artcile here that explains the basics of modals and navigation in NS Angular, but yeah - the case with tabs is a bit more complex. I created a quick playground demo here. It displays two scenarios - a modal as a child to a route in the home tab and a login modal that opens from the root app component on app start. You can actually open the second (global) one from anywhere in your app, but you will have to pass the showModal() method the ViewContainerRef of the root app component. You can save it in a service. If you want, I can add this to the playground example too.

Contributor

MartoYankov commented Aug 13, 2018

@hettiger You won't be able to open a modal page just with the router. At least we haven't figured it out yet. There is docs artcile here that explains the basics of modals and navigation in NS Angular, but yeah - the case with tabs is a bit more complex. I created a quick playground demo here. It displays two scenarios - a modal as a child to a route in the home tab and a login modal that opens from the root app component on app start. You can actually open the second (global) one from anywhere in your app, but you will have to pass the showModal() method the ViewContainerRef of the root app component. You can save it in a service. If you want, I can add this to the playground example too.

@hettiger

This comment has been minimized.

Show comment
Hide comment
@hettiger

hettiger Aug 17, 2018

@MartoYankov Thank you for the playground. That was really helpful! :-)

hettiger commented Aug 17, 2018

@MartoYankov Thank you for the playground. That was really helpful! :-)

@mendeljacks

This comment has been minimized.

Show comment
Hide comment
@mendeljacks

mendeljacks Aug 21, 2018

Trying to achieve the functionality described in scenario 1, login page and a tab view, would there be a way to achieve this without a modal by using angular router instead of nsrouter for the login page? I have been fiddling with a modal, ngIf and [visibility] to recreate the effect of an actual login route but modals just dont cut it.

mendeljacks commented Aug 21, 2018

Trying to achieve the functionality described in scenario 1, login page and a tab view, would there be a way to achieve this without a modal by using angular router instead of nsrouter for the login page? I have been fiddling with a modal, ngIf and [visibility] to recreate the effect of an actual login route but modals just dont cut it.

@mendeljacks

This comment has been minimized.

Show comment
Hide comment
@mendeljacks

mendeljacks Aug 21, 2018

My desired structure is:

const routes: Routes = [
    { path: "", redirectTo: "login", pathMatch: "full" },
    { path: "login", component: LoginComponent },
    { path: "home", children: [
       { path: "", redirectTo: "/(ordersTab:orders//productsTab:products//shelvesTab:shelves)", pathMatch: "full" },
        { path: "orders", component: OrdersComponent, outlet: "ordersTab" },
        { path: "products", component: ProductsComponent, outlet: "productsTab" },
        { path: "shelves", component: ShelvesComponent, outlet: "shelvesTab" },
    ]}
    
];

could it be that the pathMatch full is messing with the nested routes?

mendeljacks commented Aug 21, 2018

My desired structure is:

const routes: Routes = [
    { path: "", redirectTo: "login", pathMatch: "full" },
    { path: "login", component: LoginComponent },
    { path: "home", children: [
       { path: "", redirectTo: "/(ordersTab:orders//productsTab:products//shelvesTab:shelves)", pathMatch: "full" },
        { path: "orders", component: OrdersComponent, outlet: "ordersTab" },
        { path: "products", component: ProductsComponent, outlet: "productsTab" },
        { path: "shelves", component: ShelvesComponent, outlet: "shelvesTab" },
    ]}
    
];

could it be that the pathMatch full is messing with the nested routes?

@chrisbekas

This comment has been minimized.

Show comment
Hide comment
@chrisbekas

chrisbekas Aug 24, 2018

I gather this is also an issue for {N} core? I've trying to navigate to my login frame (unsuccessfully) using application.run(). Question over on stackoverflow.

chrisbekas commented Aug 24, 2018

I gather this is also an issue for {N} core? I've trying to navigate to my login frame (unsuccessfully) using application.run(). Question over on stackoverflow.

@MartoYankov

This comment has been minimized.

Show comment
Hide comment
@MartoYankov

MartoYankov Aug 24, 2018

Contributor

@chrisbekas Actually, this is quite possible to implement in {N} core. I answered your SO question.

The reason why this works in {N} core and not in NG is because of the default NG location history, which is browser based and linear. Nesting frames combined with tab navigation creates a non-linear history which must be handled differently. In other words, the main problem with nesting PROs is the back navigation. We`re actively working on this issue.

@mendeljacks The structure you specified should be possible. It's possible the redirect doesn't work, but you can navigate directly from login to home/(ordersTab:orders//productsTab:products//shelvesTab:shelves). However, as I mentioned above the back navigation in this scenario won't work correctly.

Contributor

MartoYankov commented Aug 24, 2018

@chrisbekas Actually, this is quite possible to implement in {N} core. I answered your SO question.

The reason why this works in {N} core and not in NG is because of the default NG location history, which is browser based and linear. Nesting frames combined with tab navigation creates a non-linear history which must be handled differently. In other words, the main problem with nesting PROs is the back navigation. We`re actively working on this issue.

@mendeljacks The structure you specified should be possible. It's possible the redirect doesn't work, but you can navigate directly from login to home/(ordersTab:orders//productsTab:products//shelvesTab:shelves). However, as I mentioned above the back navigation in this scenario won't work correctly.

@chrisbekas

This comment has been minimized.

Show comment
Hide comment
@chrisbekas

chrisbekas Aug 26, 2018

@MartoYankov Thanks so much Martin, works a treat!

chrisbekas commented Aug 26, 2018

@MartoYankov Thanks so much Martin, works a treat!

@wvegteren

This comment has been minimized.

Show comment
Hide comment
@wvegteren

wvegteren Sep 24, 2018

Is there any news about this issue? Any thoughts about timing?
This issue is blocking our next app release 😟

wvegteren commented Sep 24, 2018

Is there any news about this issue? Any thoughts about timing?
This issue is blocking our next app release 😟

@YvesCandel

This comment has been minimized.

Show comment
Hide comment
@YvesCandel

YvesCandel Sep 24, 2018

It's been 118 days since this has been reported! Is the NS team still actively developing the NS-Angular repo or...?

This is a critical issue for anyone using a TabView in their app. Do we really need to wait half a year to get a solution to problems like these?

YvesCandel commented Sep 24, 2018

It's been 118 days since this has been reported! Is the NS team still actively developing the NS-Angular repo or...?

This is a critical issue for anyone using a TabView in their app. Do we really need to wait half a year to get a solution to problems like these?

@manojdcoder

This comment has been minimized.

Show comment
Hide comment
@manojdcoder

manojdcoder Sep 24, 2018

@YvesCandel It's really unfortunate but I believe it is not a blocker at least if you use TabViews without router outlets inside and navigate to new pages on the parent outlet (like old times with {N} 3.x). It may not be desirable solution but works for now.

manojdcoder commented Sep 24, 2018

@YvesCandel It's really unfortunate but I believe it is not a blocker at least if you use TabViews without router outlets inside and navigate to new pages on the parent outlet (like old times with {N} 3.x). It may not be desirable solution but works for now.

@YvesCandel

This comment has been minimized.

Show comment
Hide comment
@YvesCandel

YvesCandel Sep 25, 2018

We need page router outlets inside of our tabviews. Otherwise you're missing out on the whole "history per tab" feature which literally every tabview app in the store has.

YvesCandel commented Sep 25, 2018

We need page router outlets inside of our tabviews. Otherwise you're missing out on the whole "history per tab" feature which literally every tabview app in the store has.

@kspearrin

This comment has been minimized.

Show comment
Hide comment
@kspearrin

kspearrin Oct 5, 2018

Looks like it is assigned to the 6.2 milestone. Is this actively being worked on?

kspearrin commented Oct 5, 2018

Looks like it is assigned to the 6.2 milestone. Is this actively being worked on?

@MartoYankov

This comment has been minimized.

Show comment
Hide comment
@MartoYankov

MartoYankov Oct 5, 2018

Contributor

@kspearrin Yes, this is actively developed. There is a branch djenkov/nested-named-outlets with the feature in progress. There is a new e2e app there - nested-router-tab-view for testing. Keep in mind there is still a lot of work to be done there.

Contributor

MartoYankov commented Oct 5, 2018

@kspearrin Yes, this is actively developed. There is a branch djenkov/nested-named-outlets with the feature in progress. There is a new e2e app there - nested-router-tab-view for testing. Keep in mind there is still a lot of work to be done there.

@keerl

This comment has been minimized.

Show comment
Hide comment
@keerl

keerl Oct 12, 2018

I discovered an alternative solution to this problem. I used Bottom Navigation instead of TabView.

Here is a sample project demonstrating it. Contains 4 tabs and a side drawer. Side drawer contains a link to a page and tab 4 contains a child page as well as a link to a normal page,

One issue: Back navigation on details page is weird. If you call routerExtensions.back() it will work, but if you press the Android back button it closes the app. Back button does not appear on iOS, but you can call routerExtensions.back() through an ActionItem in the action bar to go back.

See demo gif below:

keerl commented Oct 12, 2018

I discovered an alternative solution to this problem. I used Bottom Navigation instead of TabView.

Here is a sample project demonstrating it. Contains 4 tabs and a side drawer. Side drawer contains a link to a page and tab 4 contains a child page as well as a link to a normal page,

One issue: Back navigation on details page is weird. If you call routerExtensions.back() it will work, but if you press the Android back button it closes the app. Back button does not appear on iOS, but you can call routerExtensions.back() through an ActionItem in the action bar to go back.

See demo gif below:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment