diff --git a/packages/ember-routing/lib/helpers/link_to.js b/packages/ember-routing/lib/helpers/link_to.js index f08adb642de..eb7935ed7a8 100644 --- a/packages/ember-routing/lib/helpers/link_to.js +++ b/packages/ember-routing/lib/helpers/link_to.js @@ -38,6 +38,14 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) { return ret.concat(resolvedPaths(linkView.parameters)); } + var _createPath = function(path) { + var fullPath = 'paramsContext'; + if(path !== '') { + fullPath += '.' + path; + } + return fullPath; + }; + var LinkView = Ember.View.extend({ tagName: 'a', namedRoute: null, @@ -48,6 +56,38 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) { attributeBindings: ['href', 'title'], classNameBindings: 'active', + init: function() { + this._super.apply(this, arguments); + + var params = this.parameters.params, + length = params.length, + context = this.parameters.context, + self = this, + path, paths = Ember.A([]), i; + + set(this, 'paramsContext', context); + + for(i=0; i < length; i++) { + paths.pushObject(_createPath(params[i])); + } + + var observer = function(object, path) { + var notify = true, i; + for(i=0; i < paths.length; i++) { + if(!get(this, paths[i])) { + notify = false; + } + } + if(notify) { + this.notifyPropertyChange('href'); + } + }; + + for(i=0; i < length; i++) { + Ember.addObserver(this, paths[i], this, observer); + } + }, + // Even though this isn't a virtual view, we want to treat it as if it is // so that you can access the parent with {{view.prop}} concreteView: Ember.computed(function() { diff --git a/packages/ember/tests/helpers/link_to_test.js b/packages/ember/tests/helpers/link_to_test.js index 6a9f4844aab..9a042cfbe6a 100644 --- a/packages/ember/tests/helpers/link_to_test.js +++ b/packages/ember/tests/helpers/link_to_test.js @@ -119,6 +119,45 @@ test("The {{linkTo}} helper supports URL replacement", function() { equal(replaceCount, 1, 'replaceURL should be called once'); }); +test("The {{linkTo}} helper refreshes href element when one of params changes", function() { + Router.map(function() { + this.route('post', { path: '/posts/:post_id' }); + }); + + var post = Ember.Object.create({id: '1'}), + secondPost = Ember.Object.create({id: '2'}); + + App.PostRoute = Ember.Route.extend({ + model: function(params) { + return post; + }, + + serialize: function(post) { + return { post_id: post.get('id') }; + } + }); + + Ember.TEMPLATES.index = compile('{{#linkTo "post" post id="post"}}post{{/linkTo}}'); + + App.IndexController = Ember.Controller.extend(); + var indexController = container.lookup('controller:index'); + indexController.set('post', post); + + bootApplication(); + + Ember.run(function() { router.handleURL("/"); }); + + equal(Ember.$('#post', '#qunit-fixture').attr('href'), '/posts/1', 'precond - Link has rendered href attr properly'); + + indexController.set('post', secondPost); + + equal(Ember.$('#post', '#qunit-fixture').attr('href'), '/posts/2', 'href attr was updated after one of the params had been changed'); + + indexController.set('post', null); + + equal(Ember.$('#post', '#qunit-fixture').attr('href'), '/posts/2', 'href attr does not change when one of the arguments in nullified'); +}); + test("The {{linkTo}} helper supports a custom activeClass", function() { Ember.TEMPLATES.index = Ember.Handlebars.compile("

Home

{{#linkTo about id='about-link'}}About{{/linkTo}}{{#linkTo index id='self-link' activeClass='zomg-active'}}Self{{/linkTo}}");