Skip to content
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

Refer to current state from ui-sref (e.g. for setting url parameters). #1031

Closed
olegskl opened this issue Apr 17, 2014 · 37 comments
Closed

Refer to current state from ui-sref (e.g. for setting url parameters). #1031

olegskl opened this issue Apr 17, 2014 · 37 comments
Assignees
Milestone

Comments

@olegskl
Copy link

olegskl commented Apr 17, 2014

The documentation explicitly states "You can also use relative state paths within ui-sref, just like the relative paths passed to $state.go()." However, even though we are able to refer to the current state with $state.go('.', {foo: 'bar'}) it doesn't seem to work when using ui-sref directive. I naively tried ui-sref=".({foo:'bar'})" which failed.

Of course it is possible to wire up ng-click and $state.go, but that leaves us with href-less anchors, which is not very useful from the user perspective.

I've ventured a related question on stackoverflow in case somebody had figured it out already. But it appears not to be the case.

Does this functionality exist already (maybe I just missed/misused it)? If not, should it be implemented?

@timkindberg
Copy link
Contributor

I'll be honest, we never expected the use of just a single dot (.). I'm pretty sure you can just do this though now ui-sref="{foo:'bar'}".

@olegskl
Copy link
Author

olegskl commented Apr 18, 2014

I tried <a ui-sref="{foo:'bar'}">foobar</a> too and it gave me:

Error: Could not resolve '{foo:'bar'}' from state ''

Setting up a breakpoint inside of $state.go reveals that it is called like so:

$state.go("{foo:'bar'}", null, ...)

And then the error is thrown inside $state.transitionTo, on L785. I'm using v0.2.10.

@timkindberg
Copy link
Contributor

Hmm here's the commit that added that feature.

71cad3d

@olegskl
Copy link
Author

olegskl commented Apr 18, 2014

Indeed, it's not in the 0.2.10 yet. I have cloned the master branch, built it and took the files from the "build" folder. And now <a ui-sref="{foo:'bar'}">foobar</a> works fine when I put it inside a ui-view partial, though it doesn't get updated when the current state changes (I guess I was hoping for too many things at once...).

However, if put it outside of ui-view (but still inside of ng-app of course), no matter the url, on page load I'm getting:

Error: Invalid state ref '({foo:'bar'})'

So, when the directive is outside of a ui-view, the $state.current.name in $StateRefDirective's link function is always an empty string when activating a state by navigating to a url. Thus, no href attribute is created when page is rendered.

It could be intended/unavoidable behaviour though, I'm not sure.

@timkindberg
Copy link
Contributor

Thanks for looking into it. Hopefully we'll take a look soon.

@czebe
Copy link

czebe commented May 27, 2014

We're also missing this feature. Currently there's no clean way to link back to the current state without query parameters (remove parameters and trigger state change).

@lunow
Copy link

lunow commented Aug 21, 2014

+1

@daviddeutsch
Copy link

I can confirm that this works in 0.2.11 - no more error. However, it seems like the page is still reloaded.

@thomastuts
Copy link

I just tried this out and while it works perfectly when you load the page, if I change a state (e.g. from 'dashboard' to 'explore'), it still tries to redirect the user to dashboard/5 instead of explore/5 when I hover over a link. It's like the ui-sref doesn't update the state it needs to redirect to (i.e. the current state). Any ideas on why this is?

@albertpeiro
Copy link

+1 on this. Pretty pressing for handling user-friendly async pagination.

@jaroslavrehorka
Copy link

+1

2 similar comments
@demisx
Copy link

demisx commented Mar 22, 2015

+1

@bennewton999
Copy link

+1

@zschiffelbein
Copy link

+1 using ui-sref="{foo: 'bar'}" renders the href tag on the first state and does not continue to update on state changes.

edit: Spoke too soon. I got this to work. Remove the ui-sref tag and add ng-click="$state.go('.', {foo: 'bar'})". Hope this helps.

@nateabele
Copy link
Contributor

Okay, so sounds like maybe the $watch() is wrong. If somebody can post me up a quick Plunkr I'll take a look at it.

@zschiffelbein
Copy link

Pretty sloppy, but it should give you an idea. The expected outcome is for it to stay on either the color or size route when you click on a different item. http://plnkr.co/edit/fARlus6UmokOsdRxbaoS

@dferrin
Copy link

dferrin commented Apr 26, 2015

I just updated the plunk with AngularJS 1.3.15 and ui-router 0.3.14 and the href tag still does not get updated on state change. http://plnkr.co/edit/8jZCbEVuoO4srwU8fIY5?p=preview

@nateabele
Copy link
Contributor

Okay, I see the issue. Should be able to patch it later today.

@nateabele nateabele self-assigned this Apr 27, 2015
@zivc
Copy link

zivc commented May 1, 2015

@nateabele any luck?

@darynmitchell
Copy link

Confirm I am able to switch between items in my current state by changing one param value using

<a ui-sref="{ itemId: myItem.id }">

angular 1.3.14, angular-ui-router 0.2.13

@roelentless
Copy link

This only works the first time.

<a ui-sref="{ itemId: myItem.id }">

On later changes, the itemId is correct, but the suffix part of the pageload URL is used.

Angular 1.3.15, angular-ui-router 0.2.15.

@spongessuck
Copy link

This seems to work for me:

ui-sref='.({ id: theID })'

@darynmitchell
Copy link

@RuleB I later found what you said: I was mistaken, it only worked the first time, but not on later changes. Ended up with a workaround involving marking some states as needing reload using the data object (data: { reload: true }), and then a $on('$stateChangeStart' handler to see that and perform the reload.

Seems to be working as needed (~2 months use) but feels like a fragile workaround.

@shprota
Copy link

shprota commented Oct 1, 2015

I would like to submit a possible solution for this issue.
The proposed method is to treat the dot placeholder as current state name i.e.:

ui-sref=".({locale: langCode})"

Change details:

In the ui-sref directive code:

  var update = function(val) {
    if (val) def.params = angular.copy(val);

    // If specified state is the "." placeholder, substitute it for the current state name:
    def.href = $state.href(ref.state === '.' ? $state.current.name : ref.state, def.params, def.options);

    if (active) active.$$addStateInfo(ref.state, def.params);
    if (def.href !== null) attrs.$set(type.attr, def.href);
  };

And then watch for the state change to update the href when current state changes:

  if (ref.state === '.') {
    scope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) {
      if (fromState.name !== toState.name) {
        update();
      }
    });
  }

@romain10009
Copy link

+1 for handling "."

@timricker
Copy link

+1 for an elegant notation such as "." to refer to the current state.

Has there been any further progress on this?

@burzum
Copy link

burzum commented Jan 11, 2016

+1 for the dot proposal!

@netstyler
Copy link

+1 for handling "."

@matt-hernandez
Copy link

+1 for the dot proposal!

@gztomas
Copy link

gztomas commented Jan 15, 2016

+1

2 similar comments
@vincent-ng
Copy link

+1

@mrova
Copy link

mrova commented Feb 9, 2016

+1

@nateabele
Copy link
Contributor

Anyone who would like to submit a PR to implement this is welcome to do so.

@shprota
Copy link

shprota commented Feb 10, 2016

Submitted my solution

@mrova
Copy link

mrova commented Feb 10, 2016

@shprota works for me, thanks!

@Maximaximum
Copy link

It would be great if you could merge @shprota's PR.

@christopherthielen christopherthielen added this to the 1.0.0-beta.4 milestone Nov 8, 2016
@christopherthielen
Copy link
Contributor

christopherthielen commented Nov 8, 2016

I've done some analysis on this. We can't use "." to mean "the current state" because it already has specific meaning, and it is context sensitive. A relative link is relative to its context (the state that the ui-sref was created in). This means that ui-sref="." (defined in the state called home) always links to template's state (home), even if a substate (home.foo) is the current active state.

"." cannot refer to the currently active state, and we already have syntax for parameter-only ui-srefs, but it is broken in some cases. I am fixing the existing parameter-only ui-sref syntax so it updates when the state changes. i.e., ui-sref="{ id: 345 }"


Here's an example which has two states: home and home.foo. There are both styles of ui-sref links, and their equivalent ui-state links. Note the difference in behavior (when the current state is home.foo) between links with a "." links without one.

http://plnkr.co/edit/JzuxiVezaAaW697JYE8o?p=preview


here is @zschiffelbein plunker with the new changes: http://plnkr.co/edit/Vs8FcVn1bQO60vo8HHNl?p=preview

christopherthielen added a commit that referenced this issue Nov 8, 2016
- ui-sref with only parameter values should always refer to the current state (not context sensitive)
christopherthielen added a commit that referenced this issue Nov 8, 2016
refactor(ui-sref): consolidate ui-sref/state target state processing

Related to #1031
Closes #3139
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests