Skip to content

Commit 98cd2d2

Browse files
fix(resolve): Don't re-resolve data when redirected to same state, but only dynamic params changed.
Closes #3033
1 parent 3471c42 commit 98cd2d2

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/path/node.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,23 @@ export class PathNode {
7979
*
8080
* The new path starts from root and contains any nodes that match the nodes in the second path.
8181
* Nodes are compared using their state property and parameter values.
82+
*
83+
* @param pathA the first path
84+
* @param pathB the second path
85+
* @param ignoreDynamicParams don't compare dynamic parameter values
8286
*/
83-
static matching(pathA: PathNode[], pathB: PathNode[]): PathNode[] {
87+
static matching(pathA: PathNode[], pathB: PathNode[], ignoreDynamicParams = true): PathNode[] {
8488
let matching: PathNode[] = [];
8589

8690
for (let i = 0; i < pathA.length && i < pathB.length; i++) {
8791
let a = pathA[i], b = pathB[i];
8892

8993
if (a.state !== b.state) break;
90-
if (!Param.equals(a.paramSchema, a.paramValues, b.paramValues)) break;
94+
95+
let changedParams = Param.changed(a.paramSchema, a.paramValues, b.paramValues)
96+
.filter(param => !(ignoreDynamicParams && param.dynamic));
97+
if (changedParams.length) break;
98+
9199
matching.push(a);
92100
}
93101

test/core/resolveSpec.ts

+34-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import "../matchers.ts"
44

55
import { ResolveContext, State, PathNode, Resolvable } from "../../src/core";
6-
import { omit, pick, forEach, copy } from "../../src/core";
6+
import { copy } from "../../src/core";
77

88
import Spy = jasmine.Spy;
99
import {services} from "../../src/common/coreservices";
@@ -365,6 +365,39 @@ describe('Resolvables system:', function () {
365365
done();
366366
});
367367
});
368+
369+
// Test for #2796
370+
it("should not re-resolve data, when redirecting to self with dynamic parameter update", (done) => {
371+
let $registry = router.stateRegistry;
372+
let $state = router.stateService;
373+
let $transitions = router.transitionService;
374+
let resolveCount = 0;
375+
376+
$registry.register({
377+
name: 'dynamic',
378+
url: '/dynamic/{param}',
379+
params: {
380+
param: { dynamic: true }
381+
},
382+
resolve: {
383+
data: () => {
384+
new Promise(resolve => resolve('Expensive data ' + resolveCount++))
385+
}
386+
}
387+
});
388+
389+
$transitions.onEnter({entering: "dynamic"}, trans => {
390+
if (trans.params()['param'] === 'initial')
391+
return $state.target("dynamic", { param: 'redirected' });
392+
});
393+
394+
$state.go("dynamic", { param: 'initial'}).then(() => {
395+
expect($state.current.name).toBe("dynamic");
396+
expect($state.params['param']).toBe('redirected');
397+
expect(resolveCount).toBe(1);
398+
done();
399+
});
400+
});
368401
});
369402

370403

0 commit comments

Comments
 (0)