diff --git a/packages/@ember/-internals/routing/lib/services/router.ts b/packages/@ember/-internals/routing/lib/services/router.ts index 4079bb1f484..ab114790ea5 100644 --- a/packages/@ember/-internals/routing/lib/services/router.ts +++ b/packages/@ember/-internals/routing/lib/services/router.ts @@ -4,6 +4,7 @@ import { readOnly } from '@ember/object/computed'; import { assign } from '@ember/polyfills'; import Service from '@ember/service'; import { DEBUG } from '@glimmer/env'; +import { consumeTag, tagFor } from '@glimmer/validator'; import { Transition } from 'router_js'; import EmberRouter, { QueryParam } from '../system/router'; import { extractRouteArgs, resemblesURL, shallowEqual } from '../utils'; @@ -309,6 +310,18 @@ export default class RouterService extends Service { let { routeName, models, queryParams } = extractRouteArgs(args); let routerMicrolib = this._router._routerMicrolib; + // When using isActive() in a getter, we want to entagle with the auto-tracking system + // for example, + // in + // get isBarActive() { + // return isActive('foo.bar'); + // } + // + // you'd expect isBarActive to be dirtied when the route changes. + // + // https://github.com/emberjs/ember.js/issues/19004 + consumeTag(tagFor(this._router, 'currentURL')); + // UNSAFE: casting `routeName as string` here encodes the existing // assumption but may be wrong: `extractRouteArgs` correctly returns it as // `string | undefined`. There may be bugs if `isActiveIntent` does diff --git a/packages/ember/tests/routing/router_service_test/isActive_test.js b/packages/ember/tests/routing/router_service_test/isActive_test.js index d638ea1d1c4..18021cf519f 100644 --- a/packages/ember/tests/routing/router_service_test/isActive_test.js +++ b/packages/ember/tests/routing/router_service_test/isActive_test.js @@ -1,5 +1,6 @@ import Controller from '@ember/controller'; import { RouterTestCase, moduleFor } from 'internal-test-helpers'; +import Service, { inject as service } from '@ember/service'; moduleFor( 'Router Service - isActive', @@ -33,6 +34,42 @@ moduleFor( }); } + async ['@test RouterService#isActive entangles with route transitions'](assert) { + assert.expect(6); + + this.add( + `service:foo`, + class extends Service { + @service router; + + get isChildActive() { + return this.router.isActive('parent.child'); + } + + get isSisterActive() { + return this.router.isActive('parent.sister'); + } + } + ); + + await this.visit('/'); + + let fooService = this.applicationInstance.lookup('service:foo'); + + assert.equal(fooService.isChildActive, false); + assert.equal(fooService.isSisterActive, false); + + await this.routerService.transitionTo('parent.child'); + + assert.equal(fooService.isChildActive, true); + assert.equal(fooService.isSisterActive, false); + + await this.routerService.transitionTo('parent.sister'); + + assert.equal(fooService.isChildActive, false); + assert.equal(fooService.isSisterActive, true); + } + ['@test RouterService#isActive does not eagerly instantiate controller for query params']( assert ) {