-
Notifications
You must be signed in to change notification settings - Fork 26.1k
NativeScript router outlet implementation, component caching/reuse, and private APIs #7757
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
Comments
Here's my take on it. We want to add some sort of lifecycle management for a routable component that explains what to do with a component when it's removed due to a navigation, and also what to do when a component would be instantiated. Here's one (admittedly kinda terse) way to add such an API:
Whenever We'd use a decorator here to scope this behavior just to This would allow users to programmatically define their own caching behavior (local/global LRU cache, evict the cache when memory is low, or even using different caches for different platforms based on capabilities). |
Providing such way to manage the lifecycle of components during navigation will be useful and will probably implement the need of the custom The other issue that needs to be addressed, is with the child-router when reusing a cached component. Here is the scenario: The thing to keep in mind when caching components is that you don't get a chance to reuse the DI as the constructor is already executed. |
@btford, to add to what @vakrilov said above, I was interested in details concerning the
|
Router v3.0.0 UpdateWe have migrated our custom router outlet to the v3 router. However, we are facing new set of challenges. BackgroundFor NativeScript we have implemented
Here is the page-router-outlet implementation spike. And here is a more detailed info about angular routing in NativeScript. Although, there are NativeScript specifics, the essence here is persisting and reusing component instances when navigating. This question has been raised in several other threads (#6634, #5275, #7965) and other implementation might face the same problems. Problems and ChallengesWhen navigating backwards - no new components are created. Instead they are revived form the cache. ActivatedRouteThere is no way to re-inject the new instance of ActivatedRoute passed to the outlet To overcome this we have created If there is build-in angular way of persisting components - it will have to take care of updating the RouterOutletMapThere is no way to re-inject the Obviously not a sustainable solution. However, an API to merge/update We would appreciate any thoughts on that. Perhaps @vsavkin might have some opinion if we are going in the right direction or the future version of the router will help us clear some of the hacks we currently have in the code. |
Hi, It may have been said before but here is the issues I have faced. They are not NativeScript only issues but are easily observed in {N}. BackgroundLets say you have an application that will have an infinite navigation or at least unknown level deep one. For example you have a list that shows items, each time you click on an item it navigates forward to a Page which again shows a list of items etc. The way one may handle such navigation is to create an "List" component that will be 'reused' for each navigation and when an item is the Page is pressed simply navigate to it via
Problems and ChallengesEver since the RC2, RC3 releases the above approach no longer possible since SolutionsCurrently we are making "dummy" components which is identical copies of the "List" component but simply have a different class name and use them to declare additional routes in the RouterConfig. This is not optional as it does not allow for infinite navigation as desired. It would be great if there is a way to override the default 'should reuse' condition of each Component. This will make it possible to create a Component that is never or only conditionally reused rather than count on Angular to automatically resolve if the component should be reused. |
@VladimirAmiorkov do you think we should re-open this issue ? /cc @vsavkin |
@vicb As this issues describes multiple concerns and challenges I think each of those should be addressed. From my experience the major one is the non availability of overriding if and when and component will be reused. This is a showstopper for scenarios where you would like to share the code of a component to multiple "pages" but want to achieve fill navigation history. The old You could reopen this issue or I can create a new one it doesn't matter all that matters if such functionality is or will be available in angular 2. |
/cc @mhevery |
This is my thinking on the issue. Current State:When performing navigation, the router does the following:
This is the signature of createRouterState:
Currently, the createRouterState is not customizable. As a result, you cannot "reuse" activated routes. Should Reuse:We were planning to implement support for custom "reuse" strategies. But their purpose is different. It is to make components even more short-lived that they are right now. Currently, we will reuse the same component instance when its params change. The reuse strategy would allow you to get a new component instance on any params change. Possible Solutions (before final):We are not planning to make the createRouterState step customizable before final. Possible Solutions (after final):After the final is out, we can do the following:
|
Thanks for the insights @vsavkin! Looks like the For the caching problem - I guess we have to wait until there is a way to implement custom create/cache strategy for NativeScript page navigation. |
Would really appreciate that RouterOutlet component instantiation hook (the whole thing is sounding a lot like lifecycle hooks for the routes themselves). Currently I'm using a hack 'ComponentOutlet' to handle mapping state into components (mapping data/resolvers to InputMetadata in some cases, auto-wiring up FormControls to parent groups/arrays in others) that don't know they have dynamic route state being mapped to them. Separating the concerns of state mapping from the components themselves seems like it would be another side effect of this. |
I personally prefer a page stack (push/pop/replace) than a page cache |
Now that final is out, how has the situation changed? Any information I find on this seems to be from before modules and angular 2.0.0 final. |
I have also problem when implementing a custom router outlet that cache components. I can have the same route activated many times with different parameters : users/foo, users/bar. |
Current version still missing similar functionality to 'CanReuse.routerCanReuse -> return false' . |
@DzmitryShylovich Now we only need an example and some docs, thanks for sharing this PR |
Blog post is coming soon https://twitter.com/victorsavkin/status/804128642317983744 |
I created issue with this |
any news on @michalstepien comment ? |
Not sure if I've encountered the exact same issue, but I've been having a lot of issues with components not being destroyed when navigating through pages. i.e. I'm a bit surprised to see this one still open after so many years 😕 |
Closing as obsolete. RouterOutletContract now supports custom outlets without any hacks. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Introduction
NativeScript's navigation framework uses a concept of a frame that can load different pages similar to the way frames/iframes work in a browser. The only difference is that a page that you navigate away from doesn't really get unloaded, but gets shown back immediately when the user navigates back to it.
Custom Router Outlet
To support this scenario and make it easy for users to navigate between pages and use animated transitions, we decided to build our own router outlet component (referred to as
page-router-outlet
from now on) which caches components you navigate away from, and restores them once you go back to the original page.The Hack
That works fine so far, but it requires a hack on our end -- we need to explicitly set the parent router's
_childRouter
private field when navigating back to a component or that has been loaded before to avoid breaking subsequent navigations. Here's the offending code.Solutions
We are looking for better ways to do this, something that will use supported API and doesn't break in future releases. I am not familiar with the future plans for the routing framework, but at this point even a public
setChildRouter
method looks good enough as it would guarantee that thepage-router-outlet
implementation does not break with future Angular 2 releases.Steps to reproduce and a minimal demo of the problem
Requires a mobile app, but the issue isn't really mobile specific. One would probably face the same issue when building a routing solution that uses frames/iframes to load component content or implement a scheme that caches components and reuses them on back navigation.
Other information
I discussed this with @tbosch in person, and it would be great to have @btford's feedback as well.
Similar issues have been discussed before:
Ending this wall of text with a link to the detailed description of the way routing works in NativeScript.
The text was updated successfully, but these errors were encountered: