Skip to content

Commit 175717e

Browse files
fix(transition): Do not ignore transitions which have states being entered or exited
Fix for sticky states Closes #52
1 parent 85f43cc commit 175717e

File tree

2 files changed

+61
-5
lines changed

2 files changed

+61
-5
lines changed

src/transition/transition.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,11 @@ export class Transition implements IHookRegistry {
621621
return pathA.length === matching.filter(node => !reloadState || !node.state.includes[reloadState.name]).length;
622622
};
623623

624-
if (same(this.treeChanges('from'), this.treeChanges('to'))) return "SameAsCurrent";
625-
if (pending && same(pending.treeChanges('to'), this.treeChanges('to'))) return "SameAsPending";
624+
let newTC = this.treeChanges();
625+
let pendTC = pending && pending.treeChanges();
626+
627+
if (pendTC && same(pendTC.to, newTC.to) && same(pendTC.exiting, newTC.exiting)) return "SameAsPending";
628+
if (newTC.exiting.length === 0 && newTC.entering.length === 0 && same(newTC.from, newTC.to)) return "SameAsCurrent";
626629
}
627630

628631
/**

test/stateServiceSpec.ts

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Param } from '../src/params/param';
1010
import {Rejection, RejectType} from '../src/transition/rejectFactory';
1111
import { TestingPlugin } from './_testingPlugin';
1212
import { StateDeclaration } from '../src/state/interface';
13+
import { PathNode } from '../src/path/pathNode';
1314

1415
describe('stateService', function () {
1516
let router: UIRouter;
@@ -504,14 +505,66 @@ describe('stateService', function () {
504505
await initStateTo(A);
505506
expect(enterlog).toBe('A;');
506507

507-
let promise = $state.transitionTo(A, {}); // no-op
508-
expect(promise).toBeDefined(); // but we still get a valid promise
509-
let value = await promise;
508+
try {
509+
let promise = $state.transitionTo(A, {}); // no-op
510+
await promise.transition.promise;
511+
} catch (error) {
512+
let reject = error as Rejection;
513+
expect(reject.type).toBe(RejectType.IGNORED);
514+
expect(reject.message).toMatch(/ignored/);
515+
expect($state.current).toBe(A);
516+
expect(enterlog).toBe('A;');
517+
518+
done();
519+
}
520+
});
521+
522+
it('is not ignored when reload: true option is set', async(done) => {
523+
let enterlog = "";
524+
$transitions.onEnter({ entering: 'A'}, (trans, state) => { enterlog += state.name + ";"; });
525+
await initStateTo(A);
526+
expect(enterlog).toBe('A;');
527+
528+
let value = await $state.transitionTo(A, {}, { reload: true });
510529

511530
expect(value).toBe(A);
512531
expect($state.current).toBe(A);
532+
expect(enterlog).toBe('A;A;');
533+
534+
done();
535+
});
536+
537+
it('is not ignored if any nodes are found in treechanges.entering', async(done) => {
538+
let enterlog = "";
539+
$transitions.onEnter({ entering: 'A'}, (trans, state) => { enterlog += state.name + ";"; });
540+
await initStateTo(A);
513541
expect(enterlog).toBe('A;');
514542

543+
let pathNode = new PathNode(A.$$state());
544+
$transitions.onCreate({}, trans => trans.treeChanges().entering.push(pathNode));
545+
546+
let goPromise = $state.transitionTo(A);
547+
await goPromise;
548+
await goPromise.transition.promise;
549+
550+
expect(enterlog).toBe('A;A;');
551+
552+
done();
553+
});
554+
555+
it('is not ignored if any nodes are found in treechanges.exiting', async(done) => {
556+
let exitlog = "";
557+
$transitions.onExit({ exiting: 'A'}, (trans, state) => { exitlog += state.name + ";"; });
558+
await initStateTo(A);
559+
560+
let pathNode = new PathNode(A.$$state());
561+
$transitions.onCreate({}, trans => trans.treeChanges().exiting.push(pathNode));
562+
let goPromise = $state.transitionTo(A);
563+
await goPromise;
564+
await goPromise.transition.promise;
565+
566+
expect(exitlog).toBe('A;');
567+
515568
done();
516569
});
517570

0 commit comments

Comments
 (0)