Skip to content

Commit

Permalink
[FEATURE query-params-new] Query params rewrite
Browse files Browse the repository at this point in the history
See here for some examples: https://gist.github.com/machty/8167051

Depends on Handlebars subexpressions:
handlebars-lang/handlebars.js#690
  • Loading branch information
machty committed Jan 2, 2014
1 parent 59d93b5 commit 808419c
Show file tree
Hide file tree
Showing 18 changed files with 2,494 additions and 1,693 deletions.
19 changes: 11 additions & 8 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ for a detailed explanation.

Added in [#3614](https://github.com/emberjs/ember.js/pull/3614).

* `query-params`

Add query params support to the ember router. You can now define which query
params your routes respond to, use them in your route hooks to affect model
loading or controller state, and transition query parameters with the link-to
helper and the transitionTo method.

Added in [#3182](https://github.com/emberjs/ember.js/pull/3182).
* `propertyBraceExpansion`

Adds support for brace-expansion in dependent keys, observer, and watch properties.
Expand Down Expand Up @@ -143,3 +135,14 @@ for a detailed explanation.
be wrapped in a function. Useful for integrating with 3rd party callbacks.

Added in [#3991](https://github.com/emberjs/ember.js/pull/3991).

* `query-params-new`

Add query params support to the ember router. This is a rewrite of a
previous attempt at an API for query params. You can define query
param properties on route-driven controllers with the `queryParams`
property, and any changes to those properties will cause the URL
to update, and in the other direction, any URL changes to the query
params will cause those controller properties to update.

Added in [#4008](https://github.com/emberjs/ember.js/pull/4008).
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ PATH
remote: .
specs:
ember-source (1.4.0.beta.1.canary)
handlebars-source (~> 1.2.1)
handlebars-source (~> 1.3.0)

GEM
remote: https://rubygems.org/
Expand All @@ -45,7 +45,7 @@ GEM
diff-lcs (~> 1.1)
mime-types (~> 1.15)
posix-spawn (~> 0.3.6)
handlebars-source (1.2.1)
handlebars-source (1.3.0)
json (1.8.1)
kicker (3.0.0)
listen (~> 1.3.0)
Expand Down
2 changes: 1 addition & 1 deletion ember-source.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Gem::Specification.new do |gem|

gem.version = Ember.rubygems_version_string

gem.add_dependency "handlebars-source", ["~> 1.2.1"]
gem.add_dependency "handlebars-source", ["~> 1.3.0"]

gem.files = %w(VERSION) + Dir['dist/*.js', 'lib/ember/*.rb']
end
2 changes: 1 addition & 1 deletion features.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"reduceComputed-non-array-dependencies": true,
"ember-testing-lazy-routing": true,
"ember-testing-wait-hooks": true,
"query-params": null,
"query-params-new": null,
"string-humanize": null,
"string-parameterize": null,
"propertyBraceExpansion": null,
Expand Down
30 changes: 30 additions & 0 deletions hangover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

test("routeless transitionTo in mid-transition uses transition's destination route for query params, not the router's current route", function() {
expect(2);
Router.map(function() {
this.resource('woot', { path: '/woot' }, function() {
this.route('yeah');
});
});

App.WootYeahController = Ember.Controller.extend({
queryParams: ['foo'],
foo: 'lol'
});

var redirectCount = 0;
App.WootRoute = Ember.Route.extend({
redirect: function() {
redirectCount++;
// Keep transitioning to WootYeah but alter its
// query params to foo: 'yeah'
this.transitionTo({ queryParams: { foo: 'yeah' } });
}
});

bootApplication();

Ember.run(router, 'transitionTo', 'woot.yeah');
equal(router.get('location.path'), "/woot/yeah?woot.yeah[foo]=yeah");
equal(redirectCount, 1, "redirect was only run once");
});
89 changes: 87 additions & 2 deletions packages/ember-routing/lib/ext/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
@submodule ember-routing
*/

var get = Ember.get, set = Ember.set;
var get = Ember.get, set = Ember.set,
map = Ember.EnumerableUtils.map;

var queuedQueryParamChanges = {};

Ember.ControllerMixin.reopen({
/**
Expand Down Expand Up @@ -61,7 +64,7 @@ Ember.ControllerMixin.reopen({

/**
Transition into another route while replacing the current URL, if possible.
This will replace the current history entry instead of adding a new one.
This will replace the current history entry instead of adding a new one.
Beside that, it is identical to `transitionToRoute` in all other respects.
```javascript
Expand Down Expand Up @@ -111,3 +114,85 @@ Ember.ControllerMixin.reopen({
return this.replaceRoute.apply(this, arguments);
}
});

if (Ember.FEATURES.isEnabled("query-params-new")) {
Ember.ControllerMixin.reopen({

concatenatedProperties: ['queryParams'],

queryParams: null,

_queryParamScope: null,

_finalizingQueryParams: false,
_queryParamHash: Ember.computed(function computeQueryParamHash() {

// Given: queryParams: ['foo', 'bar:baz'] on controller:thing
// _queryParamHash should yield: { 'foo': 'thing[foo]' }

var result = {};
var queryParams = this.queryParams;
if (!queryParams) {
return result;
}

for (var i = 0, len = queryParams.length; i < len; ++i) {
var full = queryParams[i];
var parts = full.split(':');
var key = parts[0];
var urlKey = parts[1];
if (!urlKey) {
if (this._queryParamScope) {
urlKey = this._queryParamScope + '[' + key + ']';
} else {
urlKey = key;
}
}
result[key] = urlKey;
}

return result;
}),

_activateQueryParamObservers: function() {
var queryParams = get(this, '_queryParamHash');

for (var k in queryParams) {
if (queryParams.hasOwnProperty(k)) {
this.addObserver(k, this, this._queryParamChanged);
}
}
},

_deactivateQueryParamObservers: function() {
var queryParams = get(this, '_queryParamHash');

for (var k in queryParams) {
if (queryParams.hasOwnProperty(k)) {
this.removeObserver(k, this, this._queryParamChanged);
}
}
},

_queryParamChanged: function(controller, key) {
if (this._finalizingQueryParams) {
var changes = this._queryParamChangesDuringSuspension;
if (changes) {
changes[key] = true;
}
return;
}

var queryParams = get(this, '_queryParamHash');
queuedQueryParamChanges[queryParams[key]] = get(this, key);
Ember.run.once(this, this._fireQueryParamTransition);
},

_fireQueryParamTransition: function() {
this.transitionToRoute({ queryParams: queuedQueryParamChanges });
queuedQueryParamChanges = {};
},

_queryParamChangesDuringSuspension: null
});
}
Loading

0 comments on commit 808419c

Please sign in to comment.