-
-
Notifications
You must be signed in to change notification settings - Fork 115
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
Suggestion: router.reload() #201
Comments
@bryanrsmith I think this is similar to the other issue we had where we proposed something like a |
@EisenbergEffect Yes, a new option The method |
That sounds good. @bryanrsmith At your earliest convenience, let's work on adding the |
Hi, After some time looking for a response I couldn't find any way I can refresh the current view. I'd like to have a way to reload the current view and forcing all the cycle to run |
+1 to this feature |
It's surprising there's no way to reload/refresh current view/view-model... I'd just expect activate method to be called again |
+1 |
This is tricky. What would it mean to refresh if there were child routers? Would you expect the entire hierarchy to be refreshed? or would you expect only the deepest child to be refreshed? Perhaps this would just be controlled with navigation strategies, but what if you want different strategies for the same view model based on whether or not there's an internal refresh? A simple way to achieve the use case above, is to extract all state into its own class and simply set that as a property on the screen. Then, whenever you want to "refresh" you simply replace the property with a new instance of the state class. You could make this really simple by manually calling the screen's own @inject(Server)
export class MyScreen {
constructor(server) {
this.server = server;
this.params = null;
this.model = null;
}
activate(params) {
this.params = params;
return this.configureModelFromParams(params);
}
reset() {
this.activate(this.params);
}
configureModelFromParams(params) {
return this.server.loadModel(params.id).then(model => this.model = model);
}
} In this case I'm showing loading a model from the server, but it could be some other more complex aggregate model derived from anything. The point is that the state doesn't reside directly in the screen. It resides in some other object that you can easily dispose of and replace. The screen then acts more like a controller, automating the process of creating that object and replacing it as needed. Additionally, this is going to be much more efficient because the screen object and its view don't need to be destroyed, re-created, rebound, etc. Only the underlying data of the screen is destroyed and recreated. The binding system will handle the rest. |
Our use case is changing permissions for the current user. Imagine the admin user who is going to the user management and change his own roles and permissions. We need the full system refresh. Everything depends on the user permissions from the very beginning, including the navigation. May be with the new permissions user will not even be able to stay on the page where he currently is. The easiest solution is user re login, but I think we can do better then this. Another use case is back end system ask front end to refresh because last user activity was too long ago and the system state is inconsistent now. Again, we need the complete refresh. |
I use this (with a ugly hack: add a dummy random parameter to the current route) quite a bit in our app. One reason (not the only one) is that we use It's not the only reason, another being that @EisenbergEffect's example is a basic model. We have complex UI with multiple independent parts and not everything can easily be reduced to a single As we don't use child routers, I am not sure if refreshing child routers is the right thing to do or not... I would lean towards yes? Could it simply be an option to the new api, with a |
@EisenbergEffect @bryanrsmith I think that in the case of child routers - if you call This would ensure that there's only a one-way flow at all times, and a predictable one, at that. A router either only reloads itself or its entire hierarchy, but never a parent router or an arbitrary child router. Finally, I think the reload function could take a NavigationStrategy as an optional parameter, if you wanted to override the configured strategy. Or, this may not be necessary at all. If there are use cases where this would not work, let's explore them. I'd like to nail this down before we begin work on it. |
That sounds reasonable to me. It might be nice to get feedback from someone who wants this feature, though. The simplest thing to do (in terms of implementation on our end) is to reload the entire router tree, respecting activation strategies. I think that would work now, there's just no helper method for making it happen. |
Is there still a plan to add the |
@bryanrsmith "reload the entire router tree" will work for us. We have two use-cases for this feature. Both will be solved. Both of them is "permission based". Current user permissions changed and it pottentially affect everything on the app. |
@bryanrsmith We need this and reload all child routers would work for us as well, mostly because we don't have child routers ;) |
+1 // if (this.fragment === fragment) return; Also similar use case to @kiryaka. Unauthorised routes are hardcoded into app. Once authorised, we need to reset router and navigate to same blank route, now configured with authorised routes. router.reset();
router.configure((config) => { ... });
router.navigate(path || '', { replace: true }); |
We are also desperately waiting on a fix for this. |
+1 |
also seems that this issue is closely related #237 (after router.reset() and router.configure() the view isn't updated) |
I am having a similar issue in which some pages are not being updated when the route changes. I see some mention of (with an ugly hack: add a dummy random parameter to the current route). Does anyone have a sample of how this hack is implemented? Thanks. |
The concern with this issue is that we we have to do a page refresh on the browser every time a user authenticates (which is when we generate the navigation menu's). The result of this is that page load feels like it takes 15sec when in actual fact it would take 3sec. yawn |
For authentication, one solution is to route the user to a "logged in page" or profile page but I want the user to stay on the current page (but refresh it based on the new authenticated status). I solved this scenario by sending an event when the user authenticates. Each view is then responsible to subscribe to this event and react accordingly. Some views does nothing, some update backing fields in the view model which in turn will update the bound elements in the view. I do however agree with this suggestion and use case. |
We also have the same problem in my company with the same usecases =>
When doing so this results in wrong translated views or in wrongly shown views. There is currently no possibility to refresh a page you always have to use observers or something like this in order to get the views refreshed. This is a pain and should be nothing that you have to do on your own. I would like to see this feature in following releases. BTW you're doing a great job with aurelia - thanks :) |
Update The culprit used to be the following line in It's not clear to me why this was changed and Note: don't forget to use determineActivationStrategy() {
return activationStrategy.invokeLifecycle;
} or otherwise the lifecycle events of your VM won't be called by default. |
@jods4, this is still an issue for us... this.router.reset();
this.router.configure(function (config) {
config.title = conf.title;
config.map(conf.menus);
}).then(() => {
this.router.navigate(path || '', { replace: true });
}); am I doing anything wrong to dynamically load the new routes?
|
@ochart2 sorry, I really don't know what you're trying to do with the dynamic router configuration. Maybe @EisenbergEffect can help. I am just using |
@jods4 The idea is to reload the router with brand new routes, and then navigate to the |
@jods4 ps getting the following when using
with the names object in |
@jods4, got it working with navigateToRoute! |
@ochart2 I think you messed up the parameters. |
That's it! |
@jods4, just realised i have another issue... if i call |
@ochart2 I don't know as I never use dynamic routes / |
I have a workaround for the menu reload: Hope it helps someone down the line. `import {bindable} from "aurelia-framework"; export class NavBar {
}` I have an Context object that holds the security of a user, part of this Context is also an event system. I bound the Navbar to an array, in this case this.router.navigation, and when the User context switch I fire an event and reload the Navbar array. This force the authFilter to reload and revaluate security. For our application, this works perfectly. I hope this helps someone. |
Here is a simple solution to refresh the page: Then, to refresh the page you just need to use the existing options: The updated code is copied below:
|
Is it possible to allow the this.router.navigate("/url/here", {activationStrategy: activationStrategy.replace}); |
+1 to get a simple way to reload current view with or without the complete child/parent router tree. I didn't want to patch aurelia-history-browser.js as suggested by @gravsten. 1/ define file reload.js : Then when you need to reload the page without reloading all the app, just call the reload module : This is far to be perfect, because :
Despite of those issues, this workaround is good enough for my use case. |
+1 for this feature and refreshing the entire hierarchy |
Is there a solution to the original problem? |
I believe that there are several workaround in the comments above. This feature is waiting a community contribution for implementation. |
What does |
@carusology activationStrategy has three modes: invoke lifecycle, replace, and no change. Invoke lifecycle is used when you're navigating to the same route with different parameters, which will use the can/Activate and can/Deactivate callbacks. Replace is used when navigating to a completely different route with a different module. No change is used when the incoming url represents no change to the route, which is important specifically in the case where you're navigating from /parent/1/child/1 to /parent/1/child/2, where the child has a invoke lifecycle and the parent is no change. This is one of the highest rated feature requests on the router, however, even after reading all of the above, I don't fully understand the use case. There was some talk of changing Authentication which made sense to me. Are there any other use cases? I'd happy to look at working on this feature request, but I don't feel like I fully understand the use case. I'm concerned I might solve the problems of some in this thread to the dissatisfaction of others. |
My use case is when the user logs out of the app, thus the app needs to reload the page... this time without any user authentication (same route, but obviously the result is different). |
@davismj Thanks for describing how Our product involves the management of data across several clinical trials. Users will only be managing data for one clinical trial at a time. However, once they are done for that trial, he or she will move on to the next one. We have done this by creating a widget that allows a user to select a different trial. When that occurs, we reload the current route with a different trial's contextual data. We want the page to act as if the user is navigating to it anew. This is because we have a small amount of animation that takes place during the loading of all of our routes that signals to the user that the page's content is being refreshed even if the visual representation of the data did not. I have pulled this off today by setting |
@carusology What do your routes look like? You probably want something like this:
Then, when you navigate from |
@gravsten Cool, thank you for the info. It seems like the one and only use case for the |
About the |
No, that is not what we want. Our routes, in a contrived example, are like this:
A trial is very much like an account for most applications. It is a required, global piece of state that is verified in a Think of an email account. If you're on your inbox (let's say Reinvoking the lifecycle causes an identical user experience to take place that occurs during all other navigation scenarios. |
In case anyone's looking for a workaround, I tried this one this.router.navigateToRoute(
YOUR_ROUTE_NAME,
{ replace: true }
); and in the router configuration configureRouter() {
config.map([
{
route: 'YOUR_ROUTE_URL',
name: YOUR_ROUTE_NAME,
activationStrategy: 'replace',
...
},
...
} |
Feature description
It would be nice to have an API
router.reload()
or similar. Basically it would navigate to the current route.Respecting activation strategies means that it could do nothing, create a new VM or just invoke the lifecycle again. I am unsure if passing options to force a different activation strategy (e.g.
invokeLifecycle
instead of default) is useful or not.As I am not using child routers or viewports, am I unsure what behavior would make sense for those.
Use cases
Use cases could be that you've performed an operation on the server (e.g. save) and the impact on your VM is complicated and you prefer to load it from scratch than try to update it.
Current solutions
Trying to use
navigate
ornavigateToRoute
is currently doomed to fail, because of this check I think:https://github.com/aurelia/history-browser/blob/master/src/index.js#L191
A workaround is to pass an additional "forcing" parameter with a random value or something that changes such as time.
The text was updated successfully, but these errors were encountered: