-
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
Changing URL without changing state #64
Comments
At the moment all state parameters are normalized to strings. This was the simplest approach to begin with, because any parameter that comes from the URL starts out as a string. It is also to ensure that in your example, navigating to '/model/123' behaves the same as transitionTo('model', { id: 123 }) and transitionTo('model', { id: '123' }). I was thinking of extending this to allow arbitrary parameter types, but they would still be able to be converted to and from strings for URL handling. I'm not sure I get your use case completely; it sounds like you're creating a new business entity of some type, and when you save it on the server you want to change the URL without changing the state? This is not something thats supported currently, and I'm not quite sure how it would work, you're expecting '/model/new' (or something like that) to map to the same state as '/model/123' and for $state to somehow know that even though 'new' and '123' are different that they represent the same parameter value? Presumably if you then navigated back from '123' to 'new' you'd actually want that to be treated as different though, so the user can create another new entity... I think the easiest way to avoid the extra server roundtrip for reloading the object is to have a service that manages the remoting, and do some caching in there. When you save a new entity, you can prepopulate it into that cache. |
Hi, I found the view change with Actually, I'd like |
I'll leave this open to revisit later -- it's definitely not trivial to address. One thing you could do is register '/model/new' with $urlRouter directly, and fetch a fresh object id from the server (without saving the object), and then redirect to '/model/(new-id)'. |
Thank you very much for the project and for your answers. Actually, what could work is The The use case: In this case, the controller mentioned in the state should know whether to go on with the state change and reloading OR it will handle the new URL on it's own. I guess, the neat & flexible solution would be to add parameter like: What do you think about that? |
P.S. I've found the other way around (change the URL and no state navigation at all). It seems, that works for me:
|
Would find very useful to have a way of changing the URL without the state change (expensive render, but want to keep URL up to date for user to be able to come back). |
@iliakan can you elaborate on how that works exactly? I'd like to add it to the FAQ. |
I was really curious, too -- it looked like an endlessly recursive listener at first glance. However, the docs say $scope.$on "returns a deregistration function for this listener". So, since the listener calls the function that it returns, and that function deregisters the listener... The listener deregisters itself the first time it is invoked -- hence it's a one-time prevention of routing when defined just-in-time before calling replace(). What jumps out at me at second glance is that $stateParams will probably still have the old values after this happens. So while the bookmarkability is achieved, any components relying on $stateParams might be misled unless they were manually updated by the app. None of this is tested, but if you did:
it might patch up the parameters. Feels like hacking... I'm always up for that! ;) User beware though... this is way deep in stuff that isn't part of the API... so expect it to break down the road, if it even works now. |
The 'dynamic parameters' feature should make this sort of thing unnecessary hopefully; you'll be able to change parameters marked as dynamic in $stateParams, and the location will update automatically, but no transition will happen. |
For anyone using this, there is a small gotcha - say you are in state with url "question/1", then use this hack to go to "question" and then, without the hack, navigate back to "question/1" - this won't trigger a state change since that's the state your app is actually in the whole time. |
Yes to be thorough you should probably deal with that, too. See https://github.com/angular-ui/ui-router/blob/master/src/state.js#L233 |
I used
Since product is an URL preassigned with a state. The app still render. |
Any news on "dynamic parameters" ? |
@zerko There were some partial efforts made, but it'll be a little while before I can take them over and complete them. |
The above hacks break with 2.7 |
@nateabele, @ksperling is there any specific issue for 'dynamic parameters' ("you'll be able to change parameters marked as dynamic in $stateParams, and the location will update automatically, but no transition will happen") to have ability to track it? This issue is closed. I've tried to search any other similar issue - found only "dynamic query params". But it seems that's other issue. |
@ksperling This should be reopened, the hack was never ideal in the first place and this is a very useful behavior. |
Something is in the works. |
+10 |
@timkindberg anything that can be shared ? I would like to help as we need this ! |
This is the prerequisite: #454 -- that's as far as anyone's gotten so far. |
+1 this is something that angular needs |
+1 with example : I have a product page where you can click on a product variant, like a color, to reload the images and such things. URL needs to change, but not the rest of the page since the only operation is Interested in any immediate workaround |
We use the following workaround: $stateProvider.state('search', {
abstract: true,
templateUrl: '/partials/search/search.html'
});
$stateProvider.state('search.widget', {
url: '/search/{params:.*}'
}); And serialize/deserialize search parameters to/from |
+1 |
+1 I have a modal that can be opened from any page, and it needs it's own URL. This is proving to be very difficult to do and is discouraging me from continuing to use AngularJS |
I wanted to refresh the query parameters based on some form change. This is working for me: $state.go('items', { value: value }, {notify:false, reload:true}) |
@davidcunha This works for me too, until I need to go to another state. |
@davidcunha @cseils yes this method doesn't really work. You'll need to use $urlRouterProvider.deferIntercept(); |
+1 the
is still not working right. When you navigate to the next view, the current view is also loaded again. |
Is there a way to just change the url? I've used a number of combinations from here but it doesn't seam to work, and I suspect it's because I actually have to change the $stateParams to their localized values. Any idea? |
I'm using this inelegant solution of changing the url and not causing the controller to fully reload when leaving the state. I put this at the top of the controller: app.controller('TestController', function($state) {
if ($state.transition) return;
...
}); Then just call: $state.go('items', { value: value },
{
// prevent the events onStart and onSuccess from firing
notify: false,
// prevent reload of the current state
reload: false,
// replace the last record when changing the params so you don't hit the back button and get old params
location: 'replace'
}); The controller still reloads when the state has changed, but it exits straight away. |
Yes. Got it to work now. The concept is as stated throughout here. //on app.run()
$rootScope.$on('$translateChangeSuccess', function(){
$rootScope.routerTranslate();
})
$rootScope.routerTranslate = function(){
if($state.$current.name){ //if there's an actual state
//newParams => iterate through params and translate them
$state.go($state.$current.name, newParams, {notify: false});
}
}; It's fine now. No reload (I was not creating a proper 'newParams' object), and only url change as intended. |
@ nmpribeiro yes that works, but when you navigate to a other url/state the current (old) state is also completly reloaded and this can create some troubles like wrong url, .... |
@squadwuschel it dependes. I am only scratching the surface since I only know angular for a couple of months. Buy here is my method:
That means, if I have a new state it will basically re-write the process once a translation is triggered. Of course, if I change state I also do this 'routerTranslate' function. So, that means when I reload to a new state, that new state will get translated as well. All the ways I've thought about it these one seams the best. This translation is done on rootScope, so no need to bother about it anymore. If there are translations, awesome, if there aren't, not a problem at all. |
Is there any change in behaviour in the new UI router 1.0 here? I've tried most, if not all, of the suggested solutions in this thread but I am not able to achieve what I want. Basically I want to show a modal (an image light box) with a specific URL, exactly like facebook does it when you look at images. The image light box modal should show up, the URL change, and when you close the modal the URL is changed back. All this so that you can copy-paste or deep-link the URL to the image if you want to. I actually have achieved the described behaviour, but not without my application reloading the controllers once I get back from my light box and start navigating again. |
I've tried almost all solutions suggested here, but couldn't make the url change work properly. When I call My route is something like this:
Has anyone found a solution for this? |
@alexandrejunges
|
@Mikaeru001 By "worked", do you mean that the transitions happen as expected, or do you mean that you manage to execute the transitions without the controller reloading when executing subsequent transitions? I think what most people is having trouble with is the latter. I've also managed to get the transitions to work precisely as I want, but my controllers keep reloading... |
@averas I mean the method works as expected. URL changes and the state stays the same. Controller is not initialized twice. On 0.2.13 I had another problem with |
@averas Or is it exactly the same problem you described? |
This is what I experience. Say that I am on state: I execute This works, the URL is replaced, nothing appears to reload or anything. I then want to get back to my previous state, so I do a: $state.go(x.y.z, stateParams, {notify: false, location: "replace"}); This also seem to work, the URL is changed, everything looks good. However, when I then do a normal transition to a sibling state, which normally only loads the last controller in the chain: $state.go(x.y.a) .. all controllers (including the ones for x and y) reload. This does only happen after I changed the URL like above. I think what most people are saying in this thread is that you do not need to go back and forth like I do for this to happen. When you start interacting after you have performed the URL-replacing trick the controller reloads. |
@averas Sorry. Can't help you with that. |
Hi @Mikaeru001, Did you change another thing? |
@Mikaeru001 I honestly believe that you will strike the same problem as soon as you start interacting in your own application, you just don't know it yet. ;-) |
@averas Probably. |
Any update on this one? I'm trying to do exactly what @averas said with 1.0, but so far no luck... |
credits to @cseils **I added |
In case anybody is wondering, this is working for me now: |
Hi Everyone. |
Here's the use case to prove my point.
I'm editing a Model. On save I want to change URL to
/model/:id
(id
comes form server), but calling$state.transitionTo('model', {id: ...})
causes the state change and hence the model is RELOADED. As if it were not on client!I'm trying to pass the existing model to the state, so that may keep it (by reusing in resolve):
state.transitionTo('model', {model: modelObject})
. But the normalization code stringifies the "model", so that's not an object any more.Is what I'm doing conceptually wrong? Is there any really good reason to keep normalization which prevents it from working?
The text was updated successfully, but these errors were encountered: