diff --git a/addon/helpers/href-to.js b/addon/helpers/href-to.js
index b131ccb..c04ba6a 100644
--- a/addon/helpers/href-to.js
+++ b/addon/helpers/href-to.js
@@ -1,26 +1,24 @@
import Em from 'ember';
-import getOwner from 'ember-getowner-polyfill';
export default Em.Helper.extend({
- compute(params) {
- let router = getOwner(this).lookup('router:main');
- if(router === undefined || router.router === undefined) {
- return;
- }
+ _routing: Em.inject.service('-routing'),
+
+ onQpsChange: Em.observer('_routing.currentState', function() {
+ this.recompute();
+ }),
+ compute(params) {
let lastParam = params[params.length - 1];
let queryParams = {};
if (lastParam && lastParam.isQueryParams) {
- queryParams = params.pop();
+ queryParams = params.pop().values;
}
-
+ let routing = this.get('_routing');
let targetRouteName = params.shift();
+ let currentQueryParams = routing.get('currentState.routerJsState.fullQueryParams');
+ queryParams = Em.merge(Em.merge({}, currentQueryParams), queryParams);
- let args = [targetRouteName];
- args.push.apply(args, params);
- args.push({ queryParams: queryParams.values });
-
- return router.generate.apply(router, args);
+ return routing.generateURL(targetRouteName, params, queryParams);
}
-});
+});
\ No newline at end of file
diff --git a/tests/dummy/app/controllers/qps.js b/tests/dummy/app/controllers/qps.js
new file mode 100644
index 0000000..116f4c7
--- /dev/null
+++ b/tests/dummy/app/controllers/qps.js
@@ -0,0 +1,8 @@
+import Em from 'ember';
+
+export default Em.Controller.extend({
+ queryParams: ['string', 'number', 'bool'],
+ string: '',
+ number: 0,
+ bool: true
+});
diff --git a/tests/dummy/app/controllers/qps/details.js b/tests/dummy/app/controllers/qps/details.js
new file mode 100644
index 0000000..945111c
--- /dev/null
+++ b/tests/dummy/app/controllers/qps/details.js
@@ -0,0 +1,8 @@
+import Em from 'ember';
+
+export default Em.Controller.extend({
+ queryParams: ['nestedString', 'nestedNumber', 'nestedBool'],
+ nestedString: '',
+ nestedNumber: 0,
+ nestedBool: true
+});
diff --git a/tests/dummy/app/controllers/qps/details/more.js b/tests/dummy/app/controllers/qps/details/more.js
new file mode 100644
index 0000000..5a83383
--- /dev/null
+++ b/tests/dummy/app/controllers/qps/details/more.js
@@ -0,0 +1,8 @@
+import Em from 'ember';
+
+export default Em.Controller.extend({
+ queryParams: ['doubleNestedString', 'doubleNestedNumber', 'doubleNestedBool'],
+ doubleNestedString: '',
+ doubleNestedNumber: 0,
+ doubleNestedBool: true
+});
diff --git a/tests/dummy/app/router.js b/tests/dummy/app/router.js
index 2e6f8de..2d51ff5 100644
--- a/tests/dummy/app/router.js
+++ b/tests/dummy/app/router.js
@@ -11,6 +11,11 @@ Router.map(function() {
this.route('first');
this.route('second');
});
+ this.route('qps', function() {
+ this.route('details', { path: ':pet_id' }, function() {
+ this.route('more');
+ });
+ });
});
export default Router;
diff --git a/tests/dummy/app/routes/qps.js b/tests/dummy/app/routes/qps.js
new file mode 100644
index 0000000..56f7ac8
--- /dev/null
+++ b/tests/dummy/app/routes/qps.js
@@ -0,0 +1,15 @@
+import Em from 'ember';
+
+export const pets = [
+ { id: 1, name: 'Toby', favouriteColor: 'brown', age: 3 },
+ { id: 2, name: 'Garfield', favouriteColor: 'orange', age: 40 },
+ { id: 3, name: 'Mikey', favouriteColor: 'red', age: 33 },
+ { id: 4, name: 'Goofy', favouriteColor: 'green', age: 38 },
+ { id: 5, name: 'Thumper', favouriteColor: 'gray', age: 2 }
+];
+
+export default Em.Route.extend({
+ model() {
+ return pets;
+ }
+});
\ No newline at end of file
diff --git a/tests/dummy/app/routes/qps/details.js b/tests/dummy/app/routes/qps/details.js
new file mode 100644
index 0000000..3995a69
--- /dev/null
+++ b/tests/dummy/app/routes/qps/details.js
@@ -0,0 +1,8 @@
+import Em from 'ember';
+import { pets } from '../qps';
+
+export default Em.Route.extend({
+ model(params) {
+ return pets.find(p => p.id.toString() === params.pet_id);
+ }
+});
\ No newline at end of file
diff --git a/tests/dummy/app/templates/about.hbs b/tests/dummy/app/templates/about.hbs
index 3ab47f8..5a5865a 100644
--- a/tests/dummy/app/templates/about.hbs
+++ b/tests/dummy/app/templates/about.hbs
@@ -13,7 +13,7 @@
[Two]
[Three]
- dynamic QP value for Three link: {{input value=dynamic}}
+ dynamic QP value for Three link: {{input id="section-attr-input" value=dynamic}}
diff --git a/tests/dummy/app/templates/application.hbs b/tests/dummy/app/templates/application.hbs
index 58d5dd3..8c7c830 100644
--- a/tests/dummy/app/templates/application.hbs
+++ b/tests/dummy/app/templates/application.hbs
@@ -7,6 +7,7 @@
[{{#link-to 'about'}}About{{/link-to}}]
[{{#link-to 'pages.first'}}First Page{{/link-to}}]
[{{#link-to 'pages.second'}}Second Page{{/link-to}}]
+ [{{#link-to 'qps.index'}}QPS index{{/link-to}}]
@@ -17,6 +18,7 @@
[First Page]
[Second Page]
[Second Page (with inner span)]
+ [QPS index]
[An anchor with no href]
[An anchor with an absolute href]
[An anchor with a download attribute]
diff --git a/tests/dummy/app/templates/qps.hbs b/tests/dummy/app/templates/qps.hbs
new file mode 100644
index 0000000..4a78a85
--- /dev/null
+++ b/tests/dummy/app/templates/qps.hbs
@@ -0,0 +1,40 @@
+
+ QPS
+
+
+
+
+
+ Link-to
+ {{#each model as |pet|}}
+ -
+ {{#link-to 'qps.details' pet}}{{pet.name}}{{/link-to}}
+
+ {{/each}}
+
+
+
+ href-to
+ {{#each model as |pet|}}
+ -
+ {{pet.name}}
+
+ {{/each}}
+
+
+
+ {{outlet}}
+
\ No newline at end of file
diff --git a/tests/dummy/app/templates/qps/details.hbs b/tests/dummy/app/templates/qps/details.hbs
new file mode 100644
index 0000000..08f96f3
--- /dev/null
+++ b/tests/dummy/app/templates/qps/details.hbs
@@ -0,0 +1,22 @@
+
+ Details of {{model.name}}
+
+
+
+ href-to for more info
+ {{#link-to 'qps.details.more' id="qps-details-more-link-to"}}link-to for more info{{/link-to}}
+ {{outlet}}
+
\ No newline at end of file
diff --git a/tests/dummy/app/templates/qps/details/more.hbs b/tests/dummy/app/templates/qps/details/more.hbs
new file mode 100644
index 0000000..2eeaf45
--- /dev/null
+++ b/tests/dummy/app/templates/qps/details/more.hbs
@@ -0,0 +1,19 @@
+
+ More data about {{model.name}}
+ favourite color: {{model.favouriteColor}} | age: {{model.age}}
+
+
+
\ No newline at end of file
diff --git a/tests/integration/href-to-test.js b/tests/integration/href-to-test.js
index 0d505c7..d78b9cc 100644
--- a/tests/integration/href-to-test.js
+++ b/tests/integration/href-to-test.js
@@ -64,17 +64,6 @@ test('clicking a href-to to a nested route', function(assert) {
});
});
-test('clicking a href-to with query params', function(assert) {
- visit('/');
- leftClick('#href-to-links a:contains(About)');
- leftClick('#about-href-to-links a:contains(Two)');
- andThen(function() {
- assert.equal(currentURL(), '/about?section=two');
- assertAnchorIsActive('#link-to-links a:contains(About)', assert);
- assertAnchorIsActive('#about-link-to-links a:contains(Two)', assert);
- });
-});
-
test('clicking an action works', function(assert) {
visit('/about');
leftClick('a:contains(Increment)');
@@ -93,3 +82,68 @@ test('clicking a href-to to should propagate events and prevent default ', funct
assert.equal(event.isPropagationStopped(), false, 'should not stop propagation');
});
});
+
+// Query params
+test('clicking a link with explicit query params ({{href-to "route.name" foo=bar}})', function(assert) {
+ visit('/');
+ leftClick('#href-to-links a:contains(About)');
+ leftClick('#about-href-to-links a:contains(Two)');
+ andThen(function() {
+ assert.equal(currentURL(), '/about?section=two');
+ assertAnchorIsActive('#link-to-links a:contains(About)', assert);
+ assertAnchorIsActive('#about-link-to-links a:contains(Two)', assert);
+ });
+});
+
+test('updating a param passed to href-to ({{href-to "route.name" foo=bar}}) updates the url of the anchor', function(assert) {
+ visit('/about');
+ andThen(function() {
+ assert.equal(find('#about-href-to-links a:contains(Three)').attr('href'), '/about?section=hello');
+ fillIn('#section-attr-input', 'bye');
+ });
+ andThen(function() {
+ assert.equal(find('#about-href-to-links a:contains(Three)').attr('href'), '/about?section=bye');
+ });
+});
+
+test('links without explicitly passed query params include query params of ancestor routes, but no those of child or sibling routes', function(assert) {
+ visit('/qps');
+
+ andThen(function() {
+ assert.equal(currentURL(), '/qps');
+ assert.equal(find('#qps-href-to').attr('href'), '/qps', 'The link to the current route route has no query params');
+ assert.equal(find('.href-tos a:eq(0)').attr('href'), '/qps/1', 'The link to a child route has no query params');
+ fillIn('#qps-input-text', 'foo');
+ });
+
+ andThen(function() {
+ assert.equal(find('#qps-href-to').attr('href'), '/qps?string=foo', 'The link to a parent route has the query params defined on that route');
+ assert.equal(find('.href-tos a:eq(0)').attr('href'), '/qps/1?string=foo', 'The url the current route has the query params');
+ leftClick('.href-tos a:eq(0)');
+ });
+
+ andThen(function() {
+ assert.equal(currentURL(), '/qps/1?string=foo');
+ fillIn('#qps-input-nested-text', 'bar');
+ });
+
+ andThen(function() {
+ assert.equal(find('#qps-href-to').attr('href'), '/qps?string=foo', 'The link to a parent route has the query param defined on thar route but not in child routes');
+ assert.equal(find('.href-tos a:eq(0)').attr('href'), '/qps/1?nestedString=bar&string=foo', 'The url to the current route has the both the query params of parent routes and those in the current one');
+ assert.equal(find('.href-tos a:eq(1)').attr('href'), '/qps/2?string=foo', 'The url to the current route with a different model has only the query params in the parent');
+ assert.equal(find('#qps-details-more-href-to').attr('href'), '/qps/1/more?nestedString=bar&string=foo', 'The url to the current route has the both the query params of parent routes and those in the current one');
+ leftClick('#qps-details-more-href-to');
+ });
+
+ andThen(function() {
+ assert.equal(currentURL(), '/qps/1?string=foo');
+ fillIn('#qps-input-double-nested-text', 'qux');
+ });
+
+ andThen(function() {
+ assert.equal(find('#qps-href-to').attr('href'), '/qps?string=foo', 'The link to a parent route has the query param defined on thar route but not in child routes');
+ assert.equal(find('.href-tos a:eq(0)').attr('href'), '/qps/1?nestedString=bar&string=foo', 'The url to the parent route has his query params and those of the grandparent route, but not those in the current route');
+ assert.equal(find('.href-tos a:eq(1)').attr('href'), '/qps/2?string=foo', 'The url to the parent route with a different model has only the query params in the grand parent route');
+ assert.equal(find('#qps-details-more-href-to').attr('href'), '/qps/1/more?doubleNestedString=qux&nestedString=bar&string=foo', 'The url to the current route has the both the query params of parent routes and those in the current one');
+ });
+});
\ No newline at end of file