Ember.js anchor link

The problem is that Ember used the hash part in the URL to store the current state of your application. Spontaneously i see two possible solutions.

1 - *Don't let Ember use the hash part of your URLs.* Therefore use the HTML5 history location implementation of Ember. This will result in URLs like yourdomain.com/users/1/ without #.

App.Router.reopen({
  location: 'history'
});

2 - Don't use this technique. Instead use jQuery to do the scrolling to the relevant part. This could look like this:

<ul class="nav navbar-nav pull-right">
  <li><a {{action jumpToLogin}}>Signup</a></li> 
  <li>{{#linkTo 'about'}}About{{/linkTo}}</li>
</ul>

And in the corresponding view:

App.YourView = Ember.View.extend({
  jumpToLogin : function(){
    $('html, body').animate({
        scrollTop: $("#login").offset().top
    }, 2000);
  }
});

This may seem a lot of code for this small feature, but i guess this is a nicer user experience right? Actually you can improve this approach by extracting this logic into a mixin, so you don't have to repeat it over and over:

App.ScrollToMixin = Ember.Mixin.create({
  scrollDuration : 2000, //default
  scrollTo : function(selector){
    $('html, body').animate({
        scrollTop: $(selector).offset().top
    }, this.get("scrollDuration");
  )
});
// mix it into your View
App.YourView = Ember.View.extend(App.ScrollToMixin, {});

And use it in your template:

<ul class="nav navbar-nav pull-right">
  <li><a {{action scrollTo "login"}}>Signup</a></li> 
  <li>{{#linkTo 'about'}}About{{/linkTo}}</li>
</ul>

PS: I haven't tested the code with the mixin. I am not absolutely sure wether the String "login" gets passed to the action handler exactly like that. So you would have to test :-)


Query Params

Updated answer based on the Query Params approach (currently featured flag as of Dec 21 2013)

Based on alexspellers original JSFiddle, complete demo can be found here: http://jsfiddle.net/E3xPh/

In your Router, add support for query params

App.Router.map ->
  @resource 'index', path: '/', queryParams: ['anchor']

Using the Route of your choice, setup a property for the anchor query param in the setupController method.

App.IndexRoute = Em.Route.extend
  setupController: (controller, context, queryParams) ->
    controller.set 'anchorLocation', queryParams.anchor

Finally in your Controller make an observer for the anchorLocation property.

App.IndexController = Em.ArrayController.extend
  showAnchor: (->
    $elem = $(@anchorLocation)
    $scrollTo = $('body').scrollTop($elem.offset().top)
  ).observes 'anchorLocation'

Now you can use the following code in your templates to scroll to an anchor or point your browser to /#/?anchor=#login for example.

{{#linkTo anchor='#login'}}Show login{{/linkTo}}

Simple action approach

Possible answer based on what you wrote in the comments to the first answer. Hacked together something simple here.

http://jsbin.com/osEfokE/11

Clicking the Index link takes you to the IndexRoute and scrolls you to the login box, however the URL is not reflecting this change and typing #login will not work either.

App.ApplicationRoute = Ember.Route.extend({
    events: {
        goToLink: function(item, anchor) {
            var $elem = $(anchor);
            var $scrollTo = $('body').scrollTop($elem.offset().top);

            this.transitionToRoute(item.route).then($scrollTo);  //.transitionTo is depricated
        }
    }
});

Instead of using linkTo, you will use goToLink in your template when you want to scroll to an anchor.

<ul>
  <li><a href="#/" {{action goToLink "index" "#login"}}>Index</a></li>
  <li>{{#linkTo about}}About{{/linkTo}}</li>
  <li>{{#linkTo contact}}Contact{{/linkTo}}</li>
</ul>