-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Problem with reloadOnSearch: false - change in stateParams doesn't reload #1079
Comments
You are right that it doesn't care about which type of param. It was a quick fix for a large problem. A more official feature is now in master; typed params. We may even ditch this config property now. @nateabele you think we should get rid of reloadOnSearch? |
@timkindberg Yeah, it's getting killed off in the next release. |
Hi! Please consider those of us who migrate from ngRouter. I've recently switched my large application from using ngRouter to uiRouter. And it wasn't easy... The main difference here is that reloadOnSearch in ngRouter means that the same instance of the controller is going to be re-used. Typed query params are nice, but they are not the same. Basically, whenever a param changes, a new instance of controller is instantiated. Re-factoring this can be pretty huge. Any way we can fix the reloadOnSearch instead? |
state will now be reloaded if `state.reloadOnSearch = false` when doing `state.go('stateName', {reload: true})`
@timkindberg @nateabele I also don't see how typed parameters can replace |
@TEHEK A workaround is to make your state abstract and define E.g.: .state('contacts', {
url: '/contacts',
abstract: true,
template: '<h1>Contacts</h1>',
controller: ['$scope',
function($scope) {
//will not reload controller or view when contacts.content state changes
}],
onEnter: function() {
console.log("OnEnter: contacts");
}
})
.state('contacts.content', {
url: '?param1¶m2&interestedDirectivesWillWatchMe',
onEnter: function() {
console.log("OnEnter: contacts.content");
}
})
|
I'm having the same problem. I've divided up my stateParams into a structure where all the optional params that I don't want to cause a reload are in the querystring, and all the required params are in the base URL. But I can't navigate to the same state with a different param (no matter what I try, the state will not reload because I have reloadOnSearch set to false) using $state.go or transtitionTo... I've tried all the options {reload: true, inherit: false, location: true}. I've also tried to call $state.reload() which also did absolutely nothing. I definitely need something like reloadOnSearch to allow some stateParams to change without the state reloading... but I need other params to cause a reload. If reloadOnSearch did what it's name implies (only prevent reload when the querystring params change), it would be fine... but it appears to kill all reloading, even forced ones. |
@pholly @TEHEK In and of themselves, typed parameters don't replace |
+1. Tried the workaround from @pholly, but because the optional parameters are on a child state, the parent controller doesn't have access to them through $stateParams. $state.params also doesn't work as it is first loaded with the parent's params, and then the child's params are added, but since the parameters are optional, there is no way to know when/if that will happen in the parent. |
@cmcnamara87 You can use I typically need to watch a subset of E.g. //this assumes $state is on the $scope - $scope.$state
$scope.$watchCollection("{param1: $state.params.param1, param3: $state.params.param3}", function(newVal, oldVal, scope){
//$state.params.param1 or $state.params.param3 changed - do stuff
//old values are in oldVal.param1 and oldVal.param3
}); |
original angular ngRoute module has same |
I can also confirm this issue. I'm using search parameters to store minor ui variables within a route/view. |
My hilarious hack for this is as follows //set the reloadOnSearch on state to false initially in some code block // update query string here //revert reloadOnSearch on the state! |
@nateabele @christopherthielen I noticed dynamic parameters has yet to be merged into master. Is there any reason that I can't be of assistance and just do the merge and submit a PR? |
@jpmckearin yes, unfortunately we're gated on the 1.0 refactor before we add any additional major features |
So I know there is a planned "fix" with dynamic parameters, but if you're gated for an undetermined amount of time from merging it in, could we at least get the fix of having reloadOnSearch actually reload on path changes now? |
+1 |
yeah a patch fix would be nice. i know that makes refactors hard but it is a long standing bug |
This is a very important feature for my project. If I make several changes to search params and then navigate to a child state, when I call $state.go('^') only the first search params are remembered. I have spend several hours reading through the source code to try to fix this myself but it seems like it would take me a while to get up to speed. BTW thanks for creating such a useful router. |
When I click an "a" tag that only changes the search params on a page that has reloadOnSearch:false nothing happens. This seems like a related bug. For example: state1 uses reloadOnSearch:false. |
Why do you have a normal href link and not a ui-sref link? |
The bug I have described above also fails with ui-sref. I wanted to describe the problem with as few moving parts as possible. UI router ignores href clicks that do not change the state when you have reloadOnSearch:false |
Right, thats what reloadOnSearch: false means, don't reload the state when a query param changes. |
When I click an href link the url does not change when reloadOnSearch:false. That means reloadOnSearch:false is breaking normal browser functionality. My specific problem aside, A better way to make reloadOnSearch:false work is that the state should change but the view would not reload. This will cause $stateParams to be correct. This will cause $state.go('^') to work correctly and a whole bunch of other edge cases to work correctly. In its current state reloadOnSearch:false is nearly unusable because it breaks so many other things. |
I my case, i works for me create a decorator to keep sync /**
* Update update params values with reloadOnSearch:false.
*
* @param params
* Object of the change for the $stateParams.
*/
$delegate.refreshUrlWith = function refreshUrlWith(params) {
$location.search(extend(copy($stateParams),
$location.search(),
params
));
$urlRouter.update(true);
}; |
The handling of `reloadOnSearch: false` caused ui-router to avoid reloading the state in more cases than it should. The designed and documented behavior of this flag is to avoid state reload when the URL search string changes. It was also avoiding state reload when the URL path (or any non-search parameters to the state) changed, and even when state reload was explicitly requested. This change - flips the name of shouldTriggerReload (and the accompanying guard boolean, skipTriggerReloadCheck) to match the direction of the logic: shouldSkipReload and allowSkipReloadCheck - teaches shouldSkipReload to look at the types of the differing parameters, and only skip the reload if the only parameters that differ were search parameters - pulls the test for options.reload to the front of the complex boolean expression. (I think calling $state.reload() explicitly should reload a state even if it has reloadOnSearch:false. But I don't understand exactly why the test for this was where it was, and maybe there's a good reason I'm missing. Also, if the behavior I favor is deemed correct, we could also achieve that by setting allowSkipReloadCheck=false for all truthy values of options.reload, namely, if options.reload===true, and then shouldSkipReload wouldn't even need to look at options. I left a comment about this in the source too and would appreciate feedback.) Fixes angular-ui#1079. Helps with one of the cases broken in angular-ui#582.
I just sent a PR for this issue which I believe is a correct fix for the 0.2 codebase as it stands. The dynamic parameter stuff, from what I've been able to glean from in-passing references in this and a few other issue reports and PRs, looks pretty cool and I look forward to being able to use that, but I hope we can take this fix for the interim period before that lands. |
@metamatt Thanks for the PR. I modified your commit and merged it in manually. |
This plunkr demonstrates 0.2.15 reloadOnSearch functioning: http://plnkr.co/edit/5OPoKUDnn98JiKFlyEYL?p=preview |
Works for me, awesome job @metamatt! |
@nateabele where is this documented? I don't see any mention of it at https://angular-ui.github.io/ui-router/site/#/api/ui.router.util.type:Type -- any tips/pointers would be much appreciated! :-) |
@drothlis Not super well-documented, sadly: https://christopherthielen.github.io/ui-router/1.0-alpha01/classes/params.param.html#dynamic You define one like this: $stateProvider.state("foo", {
url: "/:bar",
params: {
bar: { dynamic: true }
}
}); |
this is the temporary home for 1.0 alpha docs: http://angular-ui.github.io/ui-router/feature-1.0 http://angular-ui.github.io/ui-router/feature-1.0/interfaces/params.paramdeclaration.html
|
@nateabele, @christopherthielen: Thanks, that's very helpful! :-) |
Is this in 1.5.9? My app.js includes this: Thanks. |
That looks fine. It shouldn't reload when the parameter changes. Are you using ui-router 1.0 beta? Dynamic params are not in the legacy versions. |
@christopherthielen Thank you. I use Bower for most of my packages, and it seems like for some reason they only have the legacy version on Bower. NPM'd ui-router 1.0 beta works like a charm! |
Here is my issue:
I navigate through a list of links, that display different images depending on the date in the search parameters (?from&to).
Those search parameters should not trigger a state reload. Finally, here is my state declaration:
But then a huge problem shows up! When I try to navigate through my different links, reload doesn't happen anymore, so that I cannot pass from one link to another.
After some digging in the code, I found out that when
reloadOnSearch
equals to false, triggers are always blocked because there's absolutely no checking of whether the changing parameters are search parameters or path parameters.So actually,
reloadOnSearch
doesn't work as intended and should be renamedreloadOnStateParamsChange
.I fixed the issue by checking if the state parameters that changed are search parameters or not, which seems to work fine.
Please tell me if I'm mistaking somewhere or if it is relevant, and also if you would be interested in a pull request or a plunkr.
Thanks in advance!
The text was updated successfully, but these errors were encountered: