Skip to content

Commit

Permalink
[BUGFIX] Ensure QP definitions interop with tracked props
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Garrett committed Sep 5, 2019
1 parent 7d125b7 commit 529feee
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 3 deletions.
8 changes: 7 additions & 1 deletion packages/@ember/-internals/metal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,13 @@ export { default as getProperties } from './lib/get_properties';
export { default as setProperties } from './lib/set_properties';
export { default as expandProperties } from './lib/expand_properties';

export { addObserver, activateObserver, removeObserver, flushAsyncObservers } from './lib/observer';
export {
addObserver,
activateObserver,
removeObserver,
flushAsyncObservers,
flushSyncObservers,
} from './lib/observer';
export { Mixin, aliasMethod, mixin, observer, applyMixin } from './lib/mixin';
export { default as inject, DEBUG_INJECTION_FUNCTIONS } from './lib/injected_property';
export { tagForProperty, tagFor, markObjectAsDirty, UNKNOWN_PROPERTY_TAG } from './lib/tags';
Expand Down
18 changes: 18 additions & 0 deletions packages/@ember/-internals/routing/lib/system/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { OwnedTemplate, TemplateFactory } from '@ember/-internals/glimmer';
import {
computed,
defineProperty,
descriptorForProperty,
get,
getProperties,
isEmpty,
Expand All @@ -17,9 +18,11 @@ import {
setFrameworkClass,
typeOf,
} from '@ember/-internals/runtime';
import { lookupDescriptor } from '@ember/-internals/utils';
import Controller from '@ember/controller';
import { assert, deprecate, info, isTesting } from '@ember/debug';
import { ROUTER_EVENTS } from '@ember/deprecated-features';
import { dependentKeyCompat } from '@ember/object/compat';
import { assign } from '@ember/polyfills';
import { once } from '@ember/runloop';
import { classify } from '@ember/string';
Expand Down Expand Up @@ -2005,6 +2008,21 @@ function mergeEachQueryParams(controllerQP: {}, routeQP: {}) {

function addQueryParamsObservers(controller: any, propNames: string[]) {
propNames.forEach(prop => {
if (descriptorForProperty(controller, prop) === undefined) {
let desc = lookupDescriptor(controller, prop);

if (desc !== null && (typeof desc.get === 'function' || typeof desc.set === 'function')) {
defineProperty(
controller,
prop,
dependentKeyCompat({
get: desc.get,
set: desc.set,
})
);
}
}

controller.addObserver(`${prop}.[]`, controller, controller._qpChanged);
});
}
Expand Down
4 changes: 3 additions & 1 deletion packages/@ember/runloop/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { assert } from '@ember/debug';
import { onErrorTarget } from '@ember/-internals/error-handling';
import { flushAsyncObservers } from '@ember/-internals/metal';
import { flushAsyncObservers, flushSyncObservers } from '@ember/-internals/metal';
import Backburner from 'backburner';
import { EMBER_METAL_TRACKED_PROPERTIES } from '@ember/canary-features';

Expand All @@ -17,6 +17,7 @@ function onEnd(current, next) {
currentRunLoop = next;

if (EMBER_METAL_TRACKED_PROPERTIES) {
flushSyncObservers();
flushAsyncObservers();
}
}
Expand All @@ -26,6 +27,7 @@ let flush;
if (EMBER_METAL_TRACKED_PROPERTIES) {
flush = function(queueName, next) {
if (queueName === 'render' || queueName === _rsvpErrorQueue) {
flushSyncObservers();
flushAsyncObservers();
}

Expand Down
68 changes: 67 additions & 1 deletion packages/ember/tests/routing/query_params_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { dasherize } from '@ember/string';
import { RSVP, Object as EmberObject, A as emberA } from '@ember/-internals/runtime';
import { run } from '@ember/runloop';
import { peekMeta } from '@ember/-internals/meta';
import { get, computed } from '@ember/-internals/metal';
import { get, computed, tracked } from '@ember/-internals/metal';
import { Route } from '@ember/-internals/routing';
import { PARAMS_SYMBOL } from 'router_js';

Expand Down Expand Up @@ -1581,5 +1581,71 @@ moduleFor(
let controller = this.getController('constructor');
assert.equal(get(controller, 'foo'), '999');
}

async ['@test Single query params defined with tracked properties can be on the controller and reflected in the url'](
assert
) {
assert.expect(3);

this.router.map(function() {
this.route('home', { path: '/' });
});

this.add(
`controller:home`,
Controller.extend({
queryParams: ['foo'],
foo: tracked(),
})
);

await this.visitAndAssert('/');
let controller = this.getController('home');

controller.foo = '456';
await runLoopSettled();
this.assertCurrentPath('/?foo=456');

controller.foo = '987';
await runLoopSettled();
this.assertCurrentPath('/?foo=987');
}

async ['@test Single query params defined with native getters and tracked properties can be on the controller and reflected in the url'](
assert
) {
assert.expect(3);

this.router.map(function() {
this.route('home', { path: '/' });
});

this.add(
`controller:home`,
Controller.extend({
queryParams: ['foo'],
get foo() {
return this.bar;
},

set foo(value) {
this.bar = value;
},

bar: tracked(),
})
);

await this.visitAndAssert('/');
let controller = this.getController('home');

controller.bar = '456';
await runLoopSettled();
this.assertCurrentPath('/?foo=456');

controller.bar = '987';
await runLoopSettled();
this.assertCurrentPath('/?foo=987');
}
}
);

0 comments on commit 529feee

Please sign in to comment.