From 8f1db44052900e1fc699bbf2c45eb89e93f015b6 Mon Sep 17 00:00:00 2001 From: Ryan Rauh Date: Mon, 31 Oct 2016 14:54:12 -0500 Subject: [PATCH] [BUGFIX beta] sets the controller _qpDelegate before mapping all the queryParams. In certain scenarios, if query params are shared through a service, bound query params will fire the _qpDelegate while transitioning to a new controller if the property has been modified from it's default value. Loosely related to - emberjs/ember.js#11592 Based on a previous PR - emberjs/ember.js#13981 --- packages/ember-routing/lib/system/route.js | 5 +- .../query_params_test/shared_state_test.js | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 packages/ember/tests/routing/query_params_test/shared_state_test.js diff --git a/packages/ember-routing/lib/system/route.js b/packages/ember-routing/lib/system/route.js index 44e2fe7ef72..56f3629bf52 100644 --- a/packages/ember-routing/lib/system/route.js +++ b/packages/ember-routing/lib/system/route.js @@ -1316,6 +1316,9 @@ let Route = EmberObject.extend(ActionHandler, Evented, { let queryParams = get(this, '_qp'); let states = queryParams.states; + + controller._qpDelegate = states.allowOverrides; + if (transition) { // Update the model dep values used to calculate cache keys. stashParamNames(this.router, transition.state.handlerInfos); @@ -1337,8 +1340,6 @@ let Route = EmberObject.extend(ActionHandler, Evented, { }); } - controller._qpDelegate = states.allowOverrides; - if (transition) { let qpValues = getQueryParamsFor(this, transition.state); controller.setProperties(qpValues); diff --git a/packages/ember/tests/routing/query_params_test/shared_state_test.js b/packages/ember/tests/routing/query_params_test/shared_state_test.js new file mode 100644 index 00000000000..813877d8b6d --- /dev/null +++ b/packages/ember/tests/routing/query_params_test/shared_state_test.js @@ -0,0 +1,76 @@ +import { + Controller, + Service +} from 'ember-runtime'; +import Ember from 'ember'; +import { run } from 'ember-metal'; +import { jQuery } from 'ember-views'; +import { QueryParamTestCase, moduleFor } from 'internal-test-helpers'; + +moduleFor('Query Params - shared service state', class extends QueryParamTestCase { + + boot() { + this.setupApplication(); + return this.visitApplication(); + } + + setupApplication() { + this.router.map(function() { + this.route('home', { path: '/' }); + this.route('dashboard'); + }); + + this.application.register('service:filters', Service.extend({ + shared: true + })); + + this.registerController('home', Controller.extend({ + filters: Ember.inject.service() + })); + + this.registerController('dashboard', Controller.extend({ + filters: Ember.inject.service(), + queryParams: [ + { 'filters.shared': 'shared' } + ] + })); + + this.registerTemplate('application', `{{link-to 'Home' 'home' }}
{{outlet}}
`); + this.registerTemplate('home', `{{link-to 'Dashboard' 'dashboard' }}{{input type="checkbox" id='filters-checkbox' checked=(mut filters.shared) }}`); + this.registerTemplate('dashboard', `{{link-to 'Home' 'home' }}`); + } + visitApplication() { + return this.visit('/'); + } + + ['@test can modify shared state before transition'](assert) { + assert.expect(1); + + return this.boot().then(() => { + this.$input = jQuery('#filters-checkbox'); + + // click the checkbox once to set filters.shared to false + run(this.$input, 'click'); + + return this.visit('/dashboard').then(() => { + assert.ok(true, 'expecting navigating to dashboard to succeed'); + }); + }); + } + + ['@test can modify shared state back to the default value before transition'](assert) { + assert.expect(1); + + return this.boot().then(() => { + this.$input = jQuery('#filters-checkbox'); + + // click the checkbox twice to set filters.shared to false and back to true + run(this.$input, 'click'); + run(this.$input, 'click'); + + return this.visit('/dashboard').then(() => { + assert.ok(true, 'expecting navigating to dashboard to succeed'); + }); + }); + } +});