Skip to content

Commit

Permalink
Add a refresh method to the RouterService
Browse files Browse the repository at this point in the history
This adds a `refresh` method to the RouterService as described in RFC
631

RFC PR: emberjs/rfcs#631
  • Loading branch information
Windvis committed Mar 20, 2021
1 parent 3b9c8bb commit 497bead
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 6 deletions.
45 changes: 45 additions & 0 deletions addon/initializers/setup-router-service-refresh-polyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* eslint-disable ember/no-private-routing-service */
import { assert } from '@ember/debug';

export function initialize(application) {
const RouterService = application.resolveRegistration('service:router');

RouterService.reopen({
/**
* Refreshes all currently active routes, doing a full transition.
* If a routeName is provided and refers to a currently active route,
* it will refresh only that route and its descendents.
* Returns a promise that will be resolved once the refresh is complete.
* All resetController, beforeModel, model, afterModel, redirect, and setupController
* hooks will be called again. You will get new data from the model hook.
*
* @method refresh
* @param {String} [routeName] the route to refresh (along with all child routes)
* @return Transition
* @public
*/
refresh(routeName) {
if (!routeName) {
return this._router._routerMicrolib.refresh();
}

assert(
`The route "${routeName}" was not found`,
this._router.hasRoute(routeName)
);

assert(
`The route "${routeName}" is currently not active`,
this.isActive(routeName)
);

let pivotRoute = this._router._routerMicrolib.getRoute(routeName);

return this._router._routerMicrolib.refresh(pivotRoute);
},
});
}

export default {
initialize,
};
4 changes: 4 additions & 0 deletions app/initializers/setup-router-service-refresh-polyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export {
default,
initialize,
} from 'ember-router-service-refresh-polyfill/initializers/setup-router-service-refresh-polyfill';
100 changes: 100 additions & 0 deletions tests/acceptance/router-service-refresh-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* eslint-disable ember/no-classic-classes */

import Route from '@ember/routing/route';
import { visit } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import { module, test } from 'qunit';

module('Acceptance | RouterService | refresh', function (hooks) {
setupApplicationTest(hooks);

test('it can be used to re-run the model hooks of active routes', async function (assert) {
const routerService = this.owner.lookup('service:router');

let parentCounter = 0;
this.owner.register(
'route:parent',
Route.extend({
model() {
++parentCounter;
},
})
);

let childCounter = 0;
this.owner.register(
'route:parent.child',
Route.extend({
model() {
++childCounter;
},
})
);

let sisterCounter = 0;
this.owner.register(
'route:parent.sister',
Route.extend({
model() {
++sisterCounter;
},
})
);

await visit('/');
assert.equal(parentCounter, 1);
assert.equal(childCounter, 0);
assert.equal(sisterCounter, 0);

await routerService.refresh();
assert.equal(parentCounter, 2);
assert.equal(childCounter, 0);
assert.equal(sisterCounter, 0);

await routerService.refresh('application');
assert.equal(parentCounter, 3);
assert.equal(childCounter, 0);
assert.equal(sisterCounter, 0);

await routerService.transitionTo('parent.child');
assert.equal(parentCounter, 3);
assert.equal(childCounter, 1);
assert.equal(sisterCounter, 0);

await routerService.refresh('parent.child');
assert.equal(parentCounter, 3);
assert.equal(childCounter, 2);
assert.equal(sisterCounter, 0);

await routerService.refresh('parent');
assert.equal(parentCounter, 4);
assert.equal(childCounter, 3);
assert.equal(sisterCounter, 0);

await routerService.transitionTo('parent.sister');
assert.equal(parentCounter, 4);
assert.equal(childCounter, 3);
assert.equal(sisterCounter, 1);

await routerService.refresh();
assert.equal(parentCounter, 5);
assert.equal(childCounter, 3);
assert.equal(sisterCounter, 2);
});

test('it verifies that the provided route exists', async function (assert) {
const routerService = this.owner.lookup('service:router');

assert.throws(() => {
routerService.refresh('this-route-does-not-exist');
});
});

test('it verifies that the provided route is active', async function (assert) {
const routerService = this.owner.lookup('service:router');

assert.throws(() => {
routerService.refresh('this-route-does-not-exist');
});
});
});
7 changes: 6 additions & 1 deletion tests/dummy/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ export default class Router extends EmberRouter {
rootURL = config.rootURL;
}

Router.map(function () {});
Router.map(function () {
this.route('parent', { path: '/' }, function () {
this.route('child');
this.route('sister');
});
});
5 changes: 0 additions & 5 deletions tests/dummy/app/templates/application.hbs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Application from '@ember/application';

import config from 'dummy/config/environment';
import { initialize } from 'dummy/initializers/setup-router-service-refresh-polyfill';
import { module, test } from 'qunit';
import Resolver from 'ember-resolver';
import { run } from '@ember/runloop';

module(
'Unit | Initializer | setup-router-service-refresh-polyfill',
function (hooks) {
hooks.beforeEach(function () {
this.TestApplication = class TestApplication extends Application {
modulePrefix = config.modulePrefix;
};
this.TestApplication.initializer({
name: 'initializer under test',
initialize,
});

this.application = this.TestApplication.create({
autoboot: false,
Resolver,
});
});

hooks.afterEach(function () {
run(this.application, 'destroy');
});

test('it adds the polyfilled refresh method to the RouterService', async function (assert) {
await this.application.boot();
const applicationInstance = this.application.buildInstance();
const routerService = applicationInstance.lookup('service:router');

assert.equal(typeof routerService.refresh, 'function');
});
}
);

0 comments on commit 497bead

Please sign in to comment.