-
Notifications
You must be signed in to change notification settings - Fork 3k
Add option for reloading controller when state URL parameters change #46
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
Hi, |
The controller already gets re-created when parameters change. However the behaviour is somewhat different from $route in that
|
@sqs in the line you're referring to, 'locals' will only be the same object if the state AND parameter values for the state are the same. In all other cases the view (and controller) will be reloaded. |
Got it. I'll try to come up with a jsfiddle or test case that reproduces what I was seeing. |
Just found this... I actually need the opposite: reloadOnSearch = false. this is because I need to change stuff inside the view directive and the controller when only the parameters change - but I need to keep them as before. Wondered what is the reason that its not supported? wouldnt you feel that it is wasting speed and memory? would you recommend that we add it locally for us (for example, by
) and let me join the others: GREAT PROJECT! EDIT: i've tried that, works so far in the sense that it does not cause reload. However, best if we could add a $watch on $stateParams service to get the changes. any hints would be appreciated.. |
@lmessinger what exactly are you trying to gain by not reloading the controller? Is there actually information held by the controller that you need to keep, or is it meant to be some sort of optimization? The reason to create the controller from scratch is so that it can (either itself or via the 'resolve' property of the state or view) load data based on the current parameters. It sounds to me like managing all that by hand via watches is rather complicated and error prone. Compared to actually loading some data remotely, surely the overhead of re-creating a controller is tiny, and any caching would be much better done via a service. $state also currently makes no arbitrary distinction between path and search parameters, so 'reloadOnSearch=false' would have to be something like 'reloadOnParameterChange=false'. |
Thanks @ksperling for both a great module and your answer. first about the Except from performance, which might be an issue on weaker devices, the in my system, every directive has an entry and exit animation. the plan is so far i've implemented the patch I've discussed above. but that does not thanks again
Lior Messinger |
@lmessinger Hmmm. We're going to have animation support via ngAnimate (#22). If I remember correctly, reloadOnSearch=false in $routeProvider causes the entire route change to be omitted, i.e. no $routeChangeStart / $routeChangeSuccess event etc. So if we were to follow the same logic, we would just update $stateParams, but not fire any onEnter/onExit or resolve new locals or anything. It seems like this could cause all sorts of odd effects though, for example in the current code any onExit callback that gets $stateParams injected would see the parameters that were valid when the state was first entered, and any subsequent changes would be invisible -- however this could be fixed. On the whole I'm not really convinced of the need for reload=false yet, especially for performance reasons: If performance is really an issue, we should do some profiling and see how we can make things faster without making people essentially do their own state management for parameters. As far as your watch goes, try watching $state.params; $stateParams always retains the same object identify (it can't change to a different object because its managed by $injector), only its contents change. $state.params is actually a new object when the state or any parameters change. |
Thanks @ksperling . Not sure if ngAnimate (looks very cool!) will solve it since if, upon parameters change, the view directive (and all of its child directives) will be re-created, i suspect they will be re-animated. and we dont want that if we plan to keep the view. Thanks for the watch advice |
@ksperling: I don't think it is about performance, but more about ui flicker. In my experience with angular so far so long as there are no AJAX queries (which we can cache) the page displays fairly fast, but there are a lot of things that flicker. e.g., ui-bootstrap's collapse/accordion does a little bounce, the new angular animations do their thing, my d3.js-based graphs take a moment to render, ng-show/ng-hide/ui-if sometimes starts in the wrong state and quickly flickers to the right one, etc. This is not so bad on page load (in some cases it is even done on purpose, such as animations). But if it happens when a user is navigating within a page I think it is really bad. An example: a table view with a next page button that updates the anchor part of the url to reflect which page is being shown (like gmail does). But every time you click next, the whole page flickers away and then appears again (including ui components independent of the current table page). Furthermore, the user loses the scrolling position and finds himself back at the top of the page. |
@jssebastian any idea what's causing this flicker? One thing that I've found quite odd is that e.g. ng-view adds the 'raw' template to the visible DOM before running the compile/link on it. In theory the compile and link should finish before the JS code finishes (i.e. before the browser starts rendering), but maybe this is not always true? |
@ksperling: from some more testing, things are not as bad as I assumed. Basically there seems to only be flicker if some state variable in my scope is briefly in the wrong state, which typically happens while I am loading asynchronously, so caching or keeping some state in a service should be able to fix most of these issues. If I find anything specific that I cannot fix on my side I will report it. However, my d3.js-based graphs do take a moment to re-render, and losing scrolling position remains a problem. |
@jssebastian scroll position is something we have to look at... clearly the $anchorScroll approach with it's default scroll-to-top behaviour isn't appropriate for ui-router anymore, see #110 |
So I don't know if there is a better way to do this but I had a similar problem. I had one view with a list of entities, and another that allows me to add entities. When I add the entity and submit it, the list was not being updated. I eventually found that I can use |
@brennancheung events seem like a good way of doing this sort of thing. If your sending from controller that's in a child scope of the one interested in the event you should also be able to use $scope.emit(), which should be more efficient in this case as the event would only traverse upwards, not to all other branches of the scope tree. |
Moving the discussion to #125, since the complex parameter implementation will allow this. |
If you have a
.state('mystate', {controller: 'MyCtrl', url: '/a/{id}'})
, then navigating from/a/1
to/a/2
does not trigger a controller reload. This appears to be by design (ui-router/src/viewDirective.js
Line 25 in c85f721
I can think of two ways to implement this: a
$state.reload()
function, or areloadOnParamsChange
param to state (similar toreloadOnSearch
). I can submit a PR that implements one of these if you think that is the right approach. If I am approaching this wrong, please let me know.BTW, great project! Thanks!
The text was updated successfully, but these errors were encountered: