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>