Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 991689c

Browse files
committed
Merge pull request emberjs#1503 from teddyzeenny/fix-href-nested-routes
Bug Fix: Generated href for nested routes with multiple contexts
2 parents 6e343cc + 9c4c4a0 commit 991689c

File tree

3 files changed

+74
-24
lines changed

3 files changed

+74
-24
lines changed

packages/ember-routing/lib/routable.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,27 +121,44 @@ Ember.Routable = Ember.Mixin.create({
121121
122122
@method absoluteRoute
123123
@param manager {Ember.StateManager}
124-
@param hash {Hash}
124+
@param hashes {Array}
125125
*/
126-
absoluteRoute: function(manager, hash) {
127-
var parentState = get(this, 'parentState');
128-
var path = '', generated;
126+
absoluteRoute: function(manager, hashes) {
127+
var parentState = get(this, 'parentState'),
128+
path = '',
129+
generated,
130+
currentHash;
131+
132+
// check if object passed instead of array
133+
// in this case set currentHash = hashes
134+
// this allows hashes to be a single hash
135+
// (it will be applied to state and all parents)
136+
currentHash = null;
137+
if (hashes) {
138+
if (hashes instanceof Array) {
139+
if (hashes.length > 0) {
140+
currentHash = hashes.shift();
141+
}
142+
} else {
143+
currentHash = hashes;
144+
}
145+
}
129146

130147
// If the parent state is routable, use its current path
131148
// as this route's prefix.
132149
if (get(parentState, 'isRoutable')) {
133-
path = parentState.absoluteRoute(manager, hash);
150+
path = parentState.absoluteRoute(manager, hashes);
134151
}
135152

136153
var matcher = get(this, 'routeMatcher'),
137154
serialized = manager.getStateMeta(this, 'serialized');
138155

139156
// merge the existing serialized object in with the passed
140157
// in hash.
141-
hash = hash || {};
142-
merge(hash, serialized);
158+
currentHash = currentHash || {};
159+
merge(currentHash, serialized);
143160

144-
generated = matcher && matcher.generate(hash);
161+
generated = matcher && matcher.generate(currentHash);
145162

146163
if (generated) {
147164
path = path + '/' + generated;

packages/ember-routing/lib/router.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -499,44 +499,50 @@ Ember.Router = Ember.StateManager.extend(
499499
}
500500
},
501501

502-
urlFor: function(path, hash) {
502+
urlFor: function(path, hashes) {
503503
var currentState = get(this, 'currentState') || this,
504504
state = this.findStateByPath(currentState, path);
505505

506506
Ember.assert(Ember.String.fmt("Could not find route with path '%@'", [path]), state);
507507
Ember.assert(Ember.String.fmt("To get a URL for the state '%@', it must have a `route` property.", [path]), get(state, 'routeMatcher'));
508508

509509
var location = get(this, 'location'),
510-
absoluteRoute = state.absoluteRoute(this, hash);
510+
absoluteRoute = state.absoluteRoute(this, hashes);
511511

512512
return location.formatURL(absoluteRoute);
513513
},
514514

515515
urlForEvent: function(eventName) {
516-
var contexts = Array.prototype.slice.call(arguments, 1);
517-
var currentState = get(this, 'currentState');
518-
var targetStateName = currentState.lookupEventTransition(eventName);
516+
var contexts = Array.prototype.slice.call(arguments, 1),
517+
currentState = get(this, 'currentState'),
518+
targetStateName = currentState.lookupEventTransition(eventName),
519+
targetState,
520+
hashes;
519521

520522
Ember.assert(Ember.String.fmt("You must specify a target state for event '%@' in order to link to it in the current state '%@'.", [eventName, get(currentState, 'path')]), targetStateName);
521523

522-
var targetState = this.findStateByPath(currentState, targetStateName);
524+
targetState = this.findStateByPath(currentState, targetStateName);
523525

524526
Ember.assert("Your target state name " + targetStateName + " for event " + eventName + " did not resolve to a state", targetState);
525527

526-
var hash = this.serializeRecursively(targetState, contexts, {});
527528

528-
return this.urlFor(targetStateName, hash);
529+
hashes = this.serializeRecursively(targetState, contexts, []);
530+
531+
return this.urlFor(targetStateName, hashes);
529532
},
530533

531-
serializeRecursively: function(state, contexts, hash) {
532-
var parentState,
533-
context = get(state, 'hasContext') ? contexts.pop() : null;
534-
merge(hash, state.serialize(this, context));
535-
parentState = state.get("parentState");
536-
if (parentState && parentState instanceof Ember.Route) {
537-
return this.serializeRecursively(parentState, contexts, hash);
534+
serializeRecursively: function(state, contexts, hashes) {
535+
var parentState,
536+
context = get(state, 'hasContext') ? contexts.pop() : null,
537+
hash = context ? state.serialize(this, context) : null;
538+
539+
hashes.push(hash);
540+
parentState = state.get("parentState");
541+
542+
if (parentState && parentState instanceof Ember.Route) {
543+
return this.serializeRecursively(parentState, contexts, hashes);
538544
} else {
539-
return hash;
545+
return hashes;
540546
}
541547
},
542548

packages/ember-routing/tests/routable_test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,33 @@ test("urlFor supports merging the current information for dynamic segments", fun
831831
expectURL('/dashboard/posts/1/manage/2');
832832
});
833833

834+
835+
test("urlForEvent supports nested routes that have different contexts but share property names", function() {
836+
var router = Ember.Router.create({
837+
location: locationStub,
838+
839+
root: Ember.Route.create({
840+
goToComments: Ember.Route.transitionTo('root.dashboard.posts.comments'),
841+
842+
dashboard: Ember.Route.create({
843+
route: '/dashboard',
844+
845+
posts: Ember.Route.create({
846+
route: '/posts/:id',
847+
comments: Ember.Route.create({
848+
route: '/comments/:id'
849+
})
850+
})
851+
})
852+
})
853+
});
854+
855+
var url = router.urlForEvent('goToComments', { id: 1 }, {id: 5});
856+
equal(url, "/dashboard/posts/1/comments/5");
857+
expectURL('/dashboard/posts/1/comments/5');
858+
});
859+
860+
834861
test("navigateAway is called if the URL changes", function() {
835862
var navigated = 0;
836863

0 commit comments

Comments
 (0)