Nativescript-angular: page-router-outlet include component

Created on 24 Nov 2016  路  13Comments  路  Source: NativeScript/nativescript-angular

I am trying to include a component on every page. With regular angular I'd do it this way:
<router-outlet></router-outlet><my-component></my-component>
This works, but navigation back doesn't work (this is to be expected)
I cannot substitute router-outlet with page-router-outlet, because my-component isn't present then (according to documentation, this is also expected behavior).
Can you please suggest a solution? I asked on SO, but had no luck there also.

question

All 13 comments

Hey @lukashlobil

You can take a look at this discussion where I have shown how to use router-outlet instead of page-router-outlet in our nativescript-sdk-examples-ng application. In the same example I had shown your scenario in which I have router-outlet and some other component in the main page.

Now in this application, we have used lazy loading to load the inner examples and the navigation back is realized via toggleNavButton directive.

Hey @NickIliev

Thank you for those links. It's almost what I need, let me specify some more.
I want to add a side-menu (the one from telerik-ui) and a toolbar on the bottom of the page.

I have now realized my main problem was doing this:
<router-outlet></router-outlet> <toolbar></toolbar>
and not wrapping it. Now if I put toolbar first, it gets rendered (in wrong position though).

I do not want to include toolbar manually on each template - it's dirty and also it is a new instance and I don't need that. The toolbar is pretty much static.

By navigating back I mostly meant the "hardware" android back button kills my app instead of navigating back when using router-outlet instead of page-router-outlet.

Thanks,
Lukas

Hey @lukashlobil we've found a bug introduced with the latest version of angular where you should wrap your outlet in NativeScript element in order for the navigation to work as expected. We are working on a fix and meanwhile using workarounds like this https://github.com/NativeScript/nativescript-sdk-examples-ng/blob/master/app/app.component.ts#L6-L8.

Can you try to wrap your router-outlet and toobar in NativeScript component.
e.g.

<StackLayout>
    <router-outlet"></router-outlet> 
    <toolbar></toolbar>
</StackLayout> <!-- or Gridlayout or any aother layout of your choice -->

and try to position your toolbar accordingly

I have come to the conclusion I cannot use because android back button kills the app - correct?
wrapped page-router-outlet renders the first page correctly, but on second page the toolbar is gone.
Is it solvable by using child routes?

As I ran out of options, I created a sample project, where you can see what I am dealing with:
https://github.com/lukashlobil/toolbarDemo

In master branch I use page-router-outlet and my component gets only rendered on first page, on navigation it is gone.
In router-outlet branch it gets rendered even after navigating to another page, but back button kills the app.
Can you please have a look? I feel like this is a very trivial problem and I must be overlooking something major.

do you see the second page when you navigate to it?

The page router should load the entire second page in a new page and will not load the sharedcomponent.

I see the second page.
Yes, page-router-outlet renders "over" the shared component.
router-outlet works as desired, but android hardware button shuts the app down

So it behaves as it should. The way to accomplish the task is to isolate the content that should repeat on every page in a separate component and include it on each page. You can see how this is done in this example - https://github.com/telerik/ng2-dashboard . You can use an Angular directive for this.

Sounds good?

Thank you for your suggestion.

Let's say I have 20+ pages and I have to include the and in each template? Yes I can use a directive, but I still have to include it on every page.

Also, the components included on every page get instantiated again. I don't really need / desire this behaviour. The links in toolbar are pretty much static after first initiliazation.

I understand what you are saying and this is expected request if you come from a web background.

For mobile applications (not in NativeScript in particular, but also in native iOS and native Android) the pattern is that each page is actually a new page (not just a content that is updated in the current page).

This is why we actually introduced the page-router-outlet. To enable you follow the correct UX patterns.

When you navigate from page to page the new page is instantiated from scratch and a native page transition is being done.

If you have an action bar or a side drawer or actually any content that needs to be on many pages, the pattern is to package it in a reusable block (directive, or component).

If the content is a static, the initialization cost will be minimal and actually not noticeable from the end users.

I will repeat that this is the same way the native apps are being implemented and the perceived performance is not affected by this.

I hope this makes sense. If not - please let us know and we can continue the discussion.

Thank you for thorough response.
I had to make sure I am not overlooking anything. So I basically had to hear: "you have to do it this way".
What gave me the drive to look into this deeper was the usage of router-outlet, which worked as I expected from web development (minus the back navigation) - I understand, in native terms when I used router-outlet and navigated, the content just got switched and no navigation took place. So when I pressed back, there was nothing in history and application closed itself. Makes sense.
Thank you for taking the time to make it clear for me that this is "by design".

(Would be a cool feature though)

Hey @lukashlobil, check this solution using angular's content projection, it may fit your needs. It's a shared component, showcase-layout.component, that wraps each page such as this one to have a more DRY solution.
In this case, it receives a title and can have an optional extra-header content.
It's true that the component get's "recreated" each time, but it's unnoticeable (Let shared angular service handle the logic).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NathanWalker picture NathanWalker  路  32Comments

NickIliev picture NickIliev  路  39Comments

tsonevn picture tsonevn  路  33Comments

MartoYankov picture MartoYankov  路  73Comments

morzyns picture morzyns  路  39Comments