ember-source 4.8.0-alpha.5 → 4.8.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/CHANGELOG.md +11 -2
  2. package/blueprints/helper/files/__root__/{__collection__ → helpers}/__name__.ts +0 -0
  3. package/blueprints/helper/index.js +0 -15
  4. package/blueprints/helper-test/index.js +0 -3
  5. package/blueprints/helper-test/mocha-0.12-files/__root__/__testType__/{__collection__ → helpers}/__name__-test.js +0 -0
  6. package/blueprints/helper-test/mocha-files/__root__/__testType__/{__collection__ → helpers}/__name__-test.js +0 -0
  7. package/blueprints/helper-test/mocha-rfc-232-files/__root__/__testType__/{__collection__ → helpers}/__name__-test.ts +0 -0
  8. package/blueprints/helper-test/qunit-files/__root__/__testType__/{__collection__ → helpers}/__name__-test.js +0 -0
  9. package/blueprints/helper-test/qunit-rfc-232-files/__root__/__testType__/{__collection__ → helpers}/__name__-test.ts +0 -0
  10. package/blueprints-js/helper/files/__root__/{__collection__ → helpers}/__name__.js +0 -0
  11. package/blueprints-js/helper-test/mocha-0.12-files/__root__/__testType__/{__collection__ → helpers}/__name__-test.js +0 -0
  12. package/blueprints-js/helper-test/mocha-files/__root__/__testType__/{__collection__ → helpers}/__name__-test.js +0 -0
  13. package/blueprints-js/helper-test/mocha-rfc-232-files/__root__/__testType__/{__collection__ → helpers}/__name__-test.js +0 -0
  14. package/blueprints-js/helper-test/qunit-files/__root__/__testType__/{__collection__ → helpers}/__name__-test.js +0 -0
  15. package/blueprints-js/helper-test/qunit-rfc-232-files/__root__/__testType__/{__collection__ → helpers}/__name__-test.js +0 -0
  16. package/build-metadata.json +3 -3
  17. package/dist/dependencies/router_js.js +1 -1
  18. package/dist/ember-template-compiler.js +675 -18
  19. package/dist/ember-template-compiler.map +1 -1
  20. package/dist/ember-testing.js +11 -11
  21. package/dist/ember-testing.map +1 -1
  22. package/dist/ember.debug.js +19576 -20510
  23. package/dist/ember.debug.map +1 -1
  24. package/dist/header/license.js +1 -1
  25. package/dist/packages/@ember/-internals/glimmer/index.js +4 -2
  26. package/dist/packages/@ember/-internals/metal/index.js +214 -1094
  27. package/dist/packages/@ember/-internals/routing/index.js +1 -17
  28. package/dist/packages/@ember/-internals/runtime/index.js +3 -16
  29. package/dist/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +2 -1
  30. package/dist/packages/@ember/-internals/runtime/lib/mixins/action_handler.js +4 -3
  31. package/dist/packages/@ember/-internals/runtime/lib/mixins/comparable.js +1 -1
  32. package/dist/packages/@ember/-internals/runtime/lib/mixins/container_proxy.js +1 -1
  33. package/dist/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js +1 -8
  34. package/dist/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +2 -1
  35. package/dist/packages/@ember/-internals/utils/index.js +3 -3
  36. package/dist/packages/@ember/-internals/views/lib/component_lookup.js +1 -1
  37. package/dist/packages/@ember/-internals/views/lib/mixins/action_support.js +2 -1
  38. package/dist/packages/@ember/-internals/views/lib/mixins/child_views_support.js +2 -1
  39. package/dist/packages/@ember/-internals/views/lib/mixins/class_names_support.js +2 -1
  40. package/dist/packages/@ember/-internals/views/lib/mixins/view_state_support.js +1 -1
  41. package/dist/packages/@ember/-internals/views/lib/mixins/view_support.js +2 -1
  42. package/dist/packages/@ember/-internals/views/lib/system/event_dispatcher.js +1 -1
  43. package/dist/packages/@ember/-internals/views/lib/views/core_view.js +3 -1
  44. package/dist/packages/@ember/application/index.js +876 -2
  45. package/dist/packages/@ember/application/instance.js +2 -2
  46. package/dist/packages/@ember/application/namespace.js +70 -1
  47. package/dist/packages/@ember/array/index.js +1503 -2
  48. package/dist/packages/@ember/array/mutable.js +1 -1
  49. package/dist/packages/@ember/array/proxy.js +307 -1
  50. package/dist/packages/@ember/canary-features/index.js +2 -2
  51. package/dist/packages/@ember/controller/index.js +260 -3
  52. package/dist/packages/@ember/debug/container-debug-adapter.js +99 -1
  53. package/dist/packages/@ember/debug/data-adapter.js +574 -1
  54. package/dist/packages/@ember/engine/index.js +5 -5
  55. package/dist/packages/@ember/engine/instance.js +4 -4
  56. package/dist/packages/@ember/enumerable/index.js +3 -1
  57. package/dist/packages/@ember/enumerable/mutable.js +4 -0
  58. package/dist/packages/@ember/{-internals/runtime/lib/system/object.js → object/-internals.js} +4 -17
  59. package/dist/packages/@ember/object/core.js +731 -1
  60. package/dist/packages/@ember/object/evented.js +93 -2
  61. package/dist/packages/@ember/object/index.js +76 -4
  62. package/dist/packages/@ember/object/internals.js +3 -2
  63. package/dist/packages/@ember/object/lib/computed/computed_macros.js +3 -1
  64. package/dist/packages/@ember/object/lib/computed/reduce_computed_macros.js +4 -3
  65. package/dist/packages/@ember/object/mixin.js +659 -1
  66. package/dist/packages/@ember/object/observable.js +341 -1
  67. package/dist/packages/@ember/object/promise-proxy-mixin.js +150 -1
  68. package/dist/packages/@ember/object/proxy.js +10 -1
  69. package/dist/packages/@ember/routing/-internals.js +7 -0
  70. package/dist/packages/@ember/routing/auto-location.js +249 -1
  71. package/dist/packages/@ember/routing/hash-location.js +169 -1
  72. package/dist/packages/@ember/routing/history-location.js +289 -1
  73. package/dist/packages/@ember/{-internals/routing/lib/system → routing/lib}/cache.js +0 -0
  74. package/dist/packages/@ember/{-internals/routing/lib/system → routing/lib}/controller_for.js +0 -0
  75. package/dist/packages/@ember/{-internals/routing/lib/system → routing/lib}/dsl.js +0 -0
  76. package/dist/packages/@ember/{-internals/routing/lib/system → routing/lib}/engines.js +0 -0
  77. package/dist/packages/@ember/{-internals/routing/lib/system → routing/lib}/generate_controller.js +0 -0
  78. package/dist/packages/@ember/{-internals/routing/lib/location/util.js → routing/lib/location-utils.js} +0 -0
  79. package/dist/packages/@ember/{-internals/routing/lib/system → routing/lib}/query_params.js +0 -0
  80. package/dist/packages/@ember/{-internals/routing/lib/system → routing/lib}/route-info.js +0 -0
  81. package/dist/packages/@ember/{-internals/routing/lib/system → routing/lib}/router_state.js +1 -1
  82. package/dist/packages/@ember/{-internals/routing/lib/services/routing.js → routing/lib/routing-service.js} +2 -2
  83. package/dist/packages/@ember/{-internals/routing/lib/system → routing/lib}/transition.js +0 -0
  84. package/dist/packages/@ember/{-internals/routing → routing}/lib/utils.js +0 -0
  85. package/dist/packages/@ember/routing/location.js +104 -1
  86. package/dist/packages/@ember/routing/none-location.js +123 -1
  87. package/dist/packages/@ember/routing/route.js +1700 -1
  88. package/dist/packages/@ember/routing/router-service.js +510 -1
  89. package/dist/packages/@ember/routing/router.js +1666 -1
  90. package/dist/packages/@ember/service/index.js +1 -1
  91. package/dist/packages/@ember/utils/index.js +7 -2
  92. package/dist/packages/@ember/{-internals/runtime → utils}/lib/compare.js +2 -2
  93. package/dist/packages/@ember/{-internals/runtime → utils}/lib/is-equal.js +0 -0
  94. package/dist/packages/@ember/utils/lib/is_blank.js +35 -0
  95. package/dist/packages/@ember/utils/lib/is_empty.js +68 -0
  96. package/dist/packages/@ember/utils/lib/is_none.js +27 -0
  97. package/dist/packages/@ember/utils/lib/is_present.js +38 -0
  98. package/dist/packages/@ember/{-internals/runtime → utils}/lib/type-of.js +2 -2
  99. package/dist/packages/ember/index.js +47 -28
  100. package/dist/packages/ember/version.js +1 -1
  101. package/dist/packages/ember-testing/lib/adapters/adapter.js +1 -1
  102. package/dist/packages/ember-testing/lib/helpers/current_path.js +2 -2
  103. package/dist/packages/ember-testing/lib/helpers/current_route_name.js +2 -2
  104. package/dist/packages/ember-testing/lib/helpers/current_url.js +1 -1
  105. package/docs/data.json +9428 -9189
  106. package/package.json +23 -8
  107. package/types/preview/@ember/-internals/resolver.d.ts +35 -0
  108. package/types/preview/@ember/application/-private/event-dispatcher.d.ts +18 -0
  109. package/types/preview/@ember/application/-private/registry.d.ts +15 -0
  110. package/types/preview/@ember/application/deprecations.d.ts +24 -0
  111. package/types/preview/@ember/application/index.d.ts +153 -0
  112. package/types/preview/@ember/application/instance.d.ts +9 -0
  113. package/types/preview/@ember/application/tsconfig.json +3 -0
  114. package/types/preview/@ember/application/types.d.ts +29 -0
  115. package/types/preview/@ember/array/-private/enumerable.d.ts +13 -0
  116. package/types/preview/@ember/array/-private/mutable-enumerable.d.ts +13 -0
  117. package/types/preview/@ember/array/-private/native-array.d.ts +23 -0
  118. package/types/preview/@ember/array/index.d.ts +243 -0
  119. package/types/preview/@ember/array/mutable.d.ts +94 -0
  120. package/types/preview/@ember/array/proxy.d.ts +29 -0
  121. package/types/preview/@ember/array/tsconfig.json +3 -0
  122. package/types/preview/@ember/component/-private/class-names-support.d.ts +27 -0
  123. package/types/preview/@ember/component/-private/core-view.d.ts +14 -0
  124. package/types/preview/@ember/component/-private/glimmer-interfaces.d.ts +45 -0
  125. package/types/preview/@ember/component/-private/signature-utils.d.ts +107 -0
  126. package/types/preview/@ember/component/-private/view-mixin.d.ts +59 -0
  127. package/types/preview/@ember/component/helper.d.ts +122 -0
  128. package/types/preview/@ember/component/index.d.ts +132 -0
  129. package/types/preview/@ember/component/template-only.d.ts +47 -0
  130. package/types/preview/@ember/component/tsconfig.json +3 -0
  131. package/types/preview/@ember/controller/index.d.ts +48 -0
  132. package/types/preview/@ember/controller/tsconfig.json +3 -0
  133. package/types/preview/@ember/debug/container-debug-adapter.d.ts +13 -0
  134. package/types/preview/@ember/debug/data-adapter.d.ts +64 -0
  135. package/types/preview/@ember/debug/index.d.ts +98 -0
  136. package/types/preview/@ember/debug/tsconfig.json +3 -0
  137. package/types/preview/@ember/destroyable/index.d.ts +23 -0
  138. package/types/preview/@ember/destroyable/tsconfig.json +3 -0
  139. package/types/preview/@ember/engine/-private/container-proxy-mixin.d.ts +17 -0
  140. package/types/preview/@ember/engine/-private/registry-proxy-mixin.d.ts +54 -0
  141. package/types/preview/@ember/engine/-private/types/initializer.d.ts +8 -0
  142. package/types/preview/@ember/engine/index.d.ts +45 -0
  143. package/types/preview/@ember/engine/instance.d.ts +24 -0
  144. package/types/preview/@ember/engine/tsconfig.json +3 -0
  145. package/types/preview/@ember/error/index.d.ts +6 -0
  146. package/types/preview/@ember/error/tsconfig.json +3 -0
  147. package/types/preview/@ember/helper/index.d.ts +49 -0
  148. package/types/preview/@ember/helper/tsconfig.json +3 -0
  149. package/types/preview/@ember/modifier/index.d.ts +33 -0
  150. package/types/preview/@ember/modifier/tsconfig.json +3 -0
  151. package/types/preview/@ember/object/-private/action-handler.d.ts +31 -0
  152. package/types/preview/@ember/object/-private/types.d.ts +63 -0
  153. package/types/preview/@ember/object/compat.d.ts +9 -0
  154. package/types/preview/@ember/object/computed.d.ts +263 -0
  155. package/types/preview/@ember/object/core.d.ts +89 -0
  156. package/types/preview/@ember/object/evented.d.ts +45 -0
  157. package/types/preview/@ember/object/events.d.ts +47 -0
  158. package/types/preview/@ember/object/index.d.ts +126 -0
  159. package/types/preview/@ember/object/internals.d.ts +17 -0
  160. package/types/preview/@ember/object/mixin.d.ts +19 -0
  161. package/types/preview/@ember/object/observable.d.ts +89 -0
  162. package/types/preview/@ember/object/observers.d.ts +34 -0
  163. package/types/preview/@ember/object/promise-proxy-mixin.d.ts +37 -0
  164. package/types/preview/@ember/object/proxy.d.ts +27 -0
  165. package/types/preview/@ember/object/tsconfig.json +3 -0
  166. package/types/preview/@ember/owner/index.d.ts +102 -0
  167. package/types/preview/@ember/owner/tsconfig.json +3 -0
  168. package/types/preview/@ember/polyfills/index.d.ts +23 -0
  169. package/types/preview/@ember/polyfills/tsconfig.json +3 -0
  170. package/types/preview/@ember/polyfills/types.d.ts +6 -0
  171. package/types/preview/@ember/routing/-private/router-dsl.d.ts +20 -0
  172. package/types/preview/@ember/routing/auto-location.d.ts +8 -0
  173. package/types/preview/@ember/routing/hash-location.d.ts +10 -0
  174. package/types/preview/@ember/routing/history-location.d.ts +9 -0
  175. package/types/preview/@ember/routing/index.d.ts +20 -0
  176. package/types/preview/@ember/routing/none-location.d.ts +11 -0
  177. package/types/preview/@ember/routing/route-info.d.ts +74 -0
  178. package/types/preview/@ember/routing/route.d.ts +533 -0
  179. package/types/preview/@ember/routing/router-service.d.ts +351 -0
  180. package/types/preview/@ember/routing/router.d.ts +49 -0
  181. package/types/preview/@ember/routing/transition.d.ts +126 -0
  182. package/types/preview/@ember/routing/tsconfig.json +3 -0
  183. package/types/preview/@ember/routing/types.d.ts +15 -0
  184. package/types/preview/@ember/runloop/-private/backburner.d.ts +43 -0
  185. package/types/preview/@ember/runloop/-private/types.d.ts +9 -0
  186. package/types/preview/@ember/runloop/index.d.ts +175 -0
  187. package/types/preview/@ember/runloop/tsconfig.json +3 -0
  188. package/types/preview/@ember/runloop/types.d.ts +5 -0
  189. package/types/preview/@ember/service/index.d.ts +25 -0
  190. package/types/preview/@ember/service/tsconfig.json +3 -0
  191. package/types/preview/@ember/string/index.d.ts +9 -0
  192. package/types/preview/@ember/string/tsconfig.json +3 -0
  193. package/types/preview/@ember/template/-private/handlebars.d.ts +7 -0
  194. package/types/preview/@ember/template/index.d.ts +5 -0
  195. package/types/preview/@ember/template/tsconfig.json +3 -0
  196. package/types/preview/@ember/test/adapter.d.ts +22 -0
  197. package/types/preview/@ember/test/index.d.ts +49 -0
  198. package/types/preview/@ember/test/tsconfig.json +3 -0
  199. package/types/preview/@ember/utils/-private/types.d.ts +39 -0
  200. package/types/preview/@ember/utils/index.d.ts +42 -0
  201. package/types/preview/@ember/utils/tsconfig.json +3 -0
  202. package/types/preview/ember/-private/type-utils.d.ts +54 -0
  203. package/types/preview/ember/index.d.ts +381 -0
  204. package/types/preview/ember/tsconfig.json +3 -0
  205. package/types/preview/index.d.ts +120 -0
  206. package/types/preview/tsconfig.json +6 -0
  207. package/blueprints/helper/mu-files/__root__/__collection__/__name__.js +0 -7
  208. package/blueprints-js/helper/mu-files/__root__/__collection__/__name__.js +0 -7
  209. package/dist/packages/@ember/-internals/extension-support/index.js +0 -2
  210. package/dist/packages/@ember/-internals/extension-support/lib/container_debug_adapter.js +0 -96
  211. package/dist/packages/@ember/-internals/extension-support/lib/data_adapter.js +0 -576
  212. package/dist/packages/@ember/-internals/routing/lib/ext/controller.js +0 -224
  213. package/dist/packages/@ember/-internals/routing/lib/location/api.js +0 -104
  214. package/dist/packages/@ember/-internals/routing/lib/location/auto_location.js +0 -250
  215. package/dist/packages/@ember/-internals/routing/lib/location/hash_location.js +0 -170
  216. package/dist/packages/@ember/-internals/routing/lib/location/history_location.js +0 -290
  217. package/dist/packages/@ember/-internals/routing/lib/location/none_location.js +0 -124
  218. package/dist/packages/@ember/-internals/routing/lib/services/router.js +0 -506
  219. package/dist/packages/@ember/-internals/routing/lib/system/route.js +0 -1696
  220. package/dist/packages/@ember/-internals/routing/lib/system/router.js +0 -1662
  221. package/dist/packages/@ember/-internals/runtime/lib/mixins/array.js +0 -1501
  222. package/dist/packages/@ember/-internals/runtime/lib/mixins/enumerable.js +0 -3
  223. package/dist/packages/@ember/-internals/runtime/lib/mixins/evented.js +0 -91
  224. package/dist/packages/@ember/-internals/runtime/lib/mixins/mutable_enumerable.js +0 -4
  225. package/dist/packages/@ember/-internals/runtime/lib/mixins/observable.js +0 -339
  226. package/dist/packages/@ember/-internals/runtime/lib/mixins/promise_proxy.js +0 -149
  227. package/dist/packages/@ember/-internals/runtime/lib/system/array_proxy.js +0 -305
  228. package/dist/packages/@ember/-internals/runtime/lib/system/core_object.js +0 -730
  229. package/dist/packages/@ember/-internals/runtime/lib/system/namespace.js +0 -69
  230. package/dist/packages/@ember/-internals/runtime/lib/system/object_proxy.js +0 -7
  231. package/dist/packages/@ember/application/lib/application.js +0 -870
  232. package/dist/packages/@ember/controller/lib/controller_mixin.js +0 -42
  233. package/dist/packages/@ember/runloop/type-tests.ts/begin-end.test.js +0 -5
  234. package/dist/packages/@ember/runloop/type-tests.ts/bind.test.js +0 -59
  235. package/dist/packages/@ember/runloop/type-tests.ts/cancel.test.js +0 -5
  236. package/dist/packages/@ember/runloop/type-tests.ts/debounce.test.js +0 -77
  237. package/dist/packages/@ember/runloop/type-tests.ts/join.test.js +0 -38
  238. package/dist/packages/@ember/runloop/type-tests.ts/later.test.js +0 -38
  239. package/dist/packages/@ember/runloop/type-tests.ts/next.test.js +0 -38
  240. package/dist/packages/@ember/runloop/type-tests.ts/once.test.js +0 -38
  241. package/dist/packages/@ember/runloop/type-tests.ts/run.test.js +0 -38
  242. package/dist/packages/@ember/runloop/type-tests.ts/schedule-once.test.js +0 -39
  243. package/dist/packages/@ember/runloop/type-tests.ts/schedule.test.js +0 -39
  244. package/dist/packages/@ember/runloop/type-tests.ts/throttle.test.js +0 -77
@@ -1,1696 +0,0 @@
1
- var __decorate = this && this.__decorate || function (decorators, target, key, desc) {
2
- var c = arguments.length,
3
- r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
4
- d;
5
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
-
9
- import { privatize as P } from '@ember/-internals/container';
10
- import { addObserver, computed, defineProperty, descriptorForProperty, flushAsyncObservers, get, getProperties, isEmpty, set, setProperties } from '@ember/-internals/metal';
11
- import { getOwner } from '@ember/-internals/owner';
12
- import { BucketCache } from '@ember/-internals/routing';
13
- import { A as emberA, ActionHandler, Evented, Object as EmberObject, typeOf } from '@ember/-internals/runtime';
14
- import { isProxy, lookupDescriptor } from '@ember/-internals/utils';
15
- import Controller from '@ember/controller';
16
- import { assert, info, isTesting } from '@ember/debug';
17
- import EngineInstance from '@ember/engine/instance';
18
- import { dependentKeyCompat } from '@ember/object/compat';
19
- import { once } from '@ember/runloop';
20
- import { DEBUG } from '@glimmer/env';
21
- import { PARAMS_SYMBOL, STATE_SYMBOL } from 'router_js';
22
- import { calculateCacheKey, deprecateTransitionMethods, normalizeControllerQueryParams, prefixRouteNameArg, stashParamNames } from '../utils';
23
- import generateController from './generate_controller';
24
- import EmberRouter from './router';
25
- export const ROUTE_CONNECTIONS = new WeakMap();
26
- const RENDER = Symbol('render');
27
-
28
- class Route extends EmberObject.extend(ActionHandler, Evented) {
29
- constructor(owner) {
30
- super(owner);
31
- this.context = {};
32
-
33
- if (owner) {
34
- let router = owner.lookup('router:main');
35
- let bucketCache = owner.lookup(P`-bucket-cache:main`);
36
- assert('ROUTER BUG: Expected route injections to be defined on the route. This is an internal bug, please open an issue on Github if you see this message!', router instanceof EmberRouter && bucketCache instanceof BucketCache);
37
- this._router = router;
38
- this._bucketCache = bucketCache;
39
- this._topLevelViewTemplate = owner.lookup('template:-outlet');
40
- this._environment = owner.lookup('-environment:main');
41
- }
42
- }
43
- /**
44
- A hook you can implement to convert the route's model into parameters
45
- for the URL.
46
- ```app/router.js
47
- // ...
48
- Router.map(function() {
49
- this.route('post', { path: '/posts/:post_id' });
50
- });
51
- ```
52
- ```app/routes/post.js
53
- import Route from '@ember/routing/route';
54
- export default class PostRoute extends Route {
55
- model({ post_id }) {
56
- // the server returns `{ id: 12 }`
57
- return fetch(`/posts/${post_id}`;
58
- }
59
- serialize(model) {
60
- // this will make the URL `/posts/12`
61
- return { post_id: model.id };
62
- }
63
- }
64
- ```
65
- The default `serialize` method will insert the model's `id` into the
66
- route's dynamic segment (in this case, `:post_id`) if the segment contains '_id'.
67
- If the route has multiple dynamic segments or does not contain '_id', `serialize`
68
- will return `getProperties(model, params)`
69
- This method is called when `transitionTo` is called with a context
70
- in order to populate the URL.
71
- @method serialize
72
- @param {Object} model the routes model
73
- @param {Array} params an Array of parameter names for the current
74
- route (in the example, `['post_id']`.
75
- @return {Object} the serialized parameters
76
- @since 1.0.0
77
- @public
78
- */
79
-
80
-
81
- serialize(model, params) {
82
- if (params.length < 1 || !model) {
83
- return;
84
- }
85
-
86
- let object = {};
87
-
88
- if (params.length === 1) {
89
- let [name] = params;
90
- assert('has name', name);
91
-
92
- if (name in model) {
93
- object[name] = get(model, name);
94
- } else if (/_id$/.test(name)) {
95
- object[name] = get(model, 'id');
96
- } else if (isProxy(model)) {
97
- object[name] = get(model, name);
98
- }
99
- } else {
100
- object = getProperties(model, params);
101
- }
102
-
103
- return object;
104
- }
105
- /**
106
- Sets the name for this route, including a fully resolved name for routes
107
- inside engines.
108
- @private
109
- @method _setRouteName
110
- @param {String} name
111
- */
112
-
113
-
114
- _setRouteName(name) {
115
- this.routeName = name;
116
- let owner = getOwner(this);
117
- assert('Expected route to have EngineInstance as owner', owner instanceof EngineInstance);
118
- this.fullRouteName = getEngineRouteName(owner, name);
119
- }
120
- /**
121
- @private
122
- @method _stashNames
123
- */
124
-
125
-
126
- _stashNames(routeInfo, dynamicParent) {
127
- if (this._names) {
128
- return;
129
- }
130
-
131
- let names = this._names = routeInfo['_names'];
132
-
133
- if (!names.length) {
134
- routeInfo = dynamicParent;
135
- names = routeInfo && routeInfo['_names'] || [];
136
- } // SAFETY: Since `_qp` is protected we can't infer the type
137
-
138
-
139
- let qps = get(this, '_qp').qps;
140
- let namePaths = new Array(names.length);
141
-
142
- for (let a = 0; a < names.length; ++a) {
143
- namePaths[a] = `${routeInfo.name}.${names[a]}`;
144
- }
145
-
146
- for (let qp of qps) {
147
- if (qp.scope === 'model') {
148
- qp.parts = namePaths;
149
- }
150
- }
151
- }
152
- /**
153
- @private
154
- @property _activeQPChanged
155
- */
156
-
157
-
158
- _activeQPChanged(qp, value) {
159
- this._router._activeQPChanged(qp.scopedPropertyName, value);
160
- }
161
- /**
162
- @private
163
- @method _updatingQPChanged
164
- */
165
-
166
-
167
- _updatingQPChanged(qp) {
168
- this._router._updatingQPChanged(qp.urlKey);
169
- }
170
- /**
171
- Returns a hash containing the parameters of an ancestor route.
172
- You may notice that `this.paramsFor` sometimes works when referring to a
173
- child route, but this behavior should not be relied upon as only ancestor
174
- routes are certain to be loaded in time.
175
- Example
176
- ```app/router.js
177
- // ...
178
- Router.map(function() {
179
- this.route('member', { path: ':name' }, function() {
180
- this.route('interest', { path: ':interest' });
181
- });
182
- });
183
- ```
184
- ```app/routes/member.js
185
- import Route from '@ember/routing/route';
186
- export default class MemberRoute extends Route {
187
- queryParams = {
188
- memberQp: { refreshModel: true }
189
- }
190
- }
191
- ```
192
- ```app/routes/member/interest.js
193
- import Route from '@ember/routing/route';
194
- export default class MemberInterestRoute extends Route {
195
- queryParams = {
196
- interestQp: { refreshModel: true }
197
- }
198
- model() {
199
- return this.paramsFor('member');
200
- }
201
- }
202
- ```
203
- If we visit `/turing/maths?memberQp=member&interestQp=interest` the model for
204
- the `member.interest` route is a hash with:
205
- * `name`: `turing`
206
- * `memberQp`: `member`
207
- @method paramsFor
208
- @param {String} name
209
- @return {Object} hash containing the parameters of the route `name`
210
- @since 1.4.0
211
- @public
212
- */
213
-
214
-
215
- paramsFor(name) {
216
- let owner = getOwner(this);
217
- assert('Route is unexpectedly missing an owner', owner);
218
- let route = owner.lookup(`route:${name}`);
219
-
220
- if (route === undefined) {
221
- return {};
222
- }
223
-
224
- let transition = this._router._routerMicrolib.activeTransition;
225
- let state = transition ? transition[STATE_SYMBOL] : this._router._routerMicrolib.state;
226
- let fullName = route.fullRouteName;
227
- let params = Object.assign({}, state.params[fullName]);
228
- let queryParams = getQueryParamsFor(route, state);
229
- return Object.entries(queryParams).reduce((params, [key, value]) => {
230
- assert(`The route '${this.routeName}' has both a dynamic segment and query param with name '${key}'. Please rename one to avoid collisions.`, !params[key]);
231
- params[key] = value;
232
- return params;
233
- }, params);
234
- }
235
- /**
236
- Serializes the query parameter key
237
- @method serializeQueryParamKey
238
- @param {String} controllerPropertyName
239
- @private
240
- */
241
-
242
-
243
- serializeQueryParamKey(controllerPropertyName) {
244
- return controllerPropertyName;
245
- }
246
- /**
247
- Serializes value of the query parameter based on defaultValueType
248
- @method serializeQueryParam
249
- @param {Object} value
250
- @param {String} urlKey
251
- @param {String} defaultValueType
252
- @private
253
- */
254
-
255
-
256
- serializeQueryParam(value, _urlKey, defaultValueType) {
257
- // urlKey isn't used here, but anyone overriding
258
- // can use it to provide serialization specific
259
- // to a certain query param.
260
- return this._router._serializeQueryParam(value, defaultValueType);
261
- }
262
- /**
263
- Deserializes value of the query parameter based on defaultValueType
264
- @method deserializeQueryParam
265
- @param {Object} value
266
- @param {String} urlKey
267
- @param {String} defaultValueType
268
- @private
269
- */
270
-
271
-
272
- deserializeQueryParam(value, _urlKey, defaultValueType) {
273
- // urlKey isn't used here, but anyone overriding
274
- // can use it to provide deserialization specific
275
- // to a certain query param.
276
- return this._router._deserializeQueryParam(value, defaultValueType);
277
- }
278
- /**
279
- @private
280
- @property _optionsForQueryParam
281
- */
282
-
283
-
284
- _optionsForQueryParam(qp) {
285
- const queryParams = get(this, 'queryParams');
286
- return get(queryParams, qp.urlKey) || get(queryParams, qp.prop) || queryParams[qp.urlKey] || queryParams[qp.prop] || {};
287
- }
288
- /**
289
- A hook you can use to reset controller values either when the model
290
- changes or the route is exiting.
291
- ```app/routes/articles.js
292
- import Route from '@ember/routing/route';
293
- export default class ArticlesRoute extends Route {
294
- resetController(controller, isExiting, transition) {
295
- if (isExiting && transition.targetName !== 'error') {
296
- controller.set('page', 1);
297
- }
298
- }
299
- }
300
- ```
301
- @method resetController
302
- @param {Controller} controller instance
303
- @param {Boolean} isExiting
304
- @param {Object} transition
305
- @since 1.7.0
306
- @public
307
- */
308
-
309
-
310
- resetController(_controller, _isExiting, _transition) {
311
- return this;
312
- }
313
- /**
314
- @private
315
- @method exit
316
- */
317
-
318
-
319
- exit(transition) {
320
- this.deactivate(transition);
321
- this.trigger('deactivate', transition);
322
- this.teardownViews();
323
- }
324
- /**
325
- @private
326
- @method _internalReset
327
- @since 3.6.0
328
- */
329
-
330
-
331
- _internalReset(isExiting, transition) {
332
- let controller = this.controller; // SAFETY: Since `_qp` is protected we can't infer the type
333
-
334
- controller['_qpDelegate'] = get(this, '_qp').states.inactive;
335
- this.resetController(controller, isExiting, transition);
336
- }
337
- /**
338
- @private
339
- @method enter
340
- */
341
-
342
-
343
- enter(transition) {
344
- ROUTE_CONNECTIONS.set(this, []);
345
- this.activate(transition);
346
- this.trigger('activate', transition);
347
- }
348
- /**
349
- This event is triggered when the router enters the route. It is
350
- not executed when the model for the route changes.
351
- ```app/routes/application.js
352
- import { on } from '@ember/object/evented';
353
- import Route from '@ember/routing/route';
354
- export default Route.extend({
355
- collectAnalytics: on('activate', function(){
356
- collectAnalytics();
357
- })
358
- });
359
- ```
360
- @event activate
361
- @since 1.9.0
362
- @public
363
- */
364
-
365
- /**
366
- This event is triggered when the router completely exits this
367
- route. It is not executed when the model for the route changes.
368
- ```app/routes/index.js
369
- import { on } from '@ember/object/evented';
370
- import Route from '@ember/routing/route';
371
- export default Route.extend({
372
- trackPageLeaveAnalytics: on('deactivate', function(){
373
- trackPageLeaveAnalytics();
374
- })
375
- });
376
- ```
377
- @event deactivate
378
- @since 1.9.0
379
- @public
380
- */
381
-
382
- /**
383
- This hook is executed when the router completely exits this route. It is
384
- not executed when the model for the route changes.
385
- @method deactivate
386
- @param {Transition} transition
387
- @since 1.0.0
388
- @public
389
- */
390
-
391
-
392
- deactivate(_transition) {}
393
- /**
394
- This hook is executed when the router enters the route. It is not executed
395
- when the model for the route changes.
396
- @method activate
397
- @param {Transition} transition
398
- @since 1.0.0
399
- @public
400
- */
401
-
402
-
403
- activate(_transition) {}
404
- /**
405
- Transition the application into another route. The route may
406
- be either a single route or route path:
407
- ```javascript
408
- this.transitionTo('blogPosts');
409
- this.transitionTo('blogPosts.recentEntries');
410
- ```
411
- Optionally supply a model for the route in question. The model
412
- will be serialized into the URL using the `serialize` hook of
413
- the route:
414
- ```javascript
415
- this.transitionTo('blogPost', aPost);
416
- ```
417
- If a literal is passed (such as a number or a string), it will
418
- be treated as an identifier instead. In this case, the `model`
419
- hook of the route will be triggered:
420
- ```javascript
421
- this.transitionTo('blogPost', 1);
422
- ```
423
- Multiple models will be applied last to first recursively up the
424
- route tree.
425
- ```app/routes.js
426
- // ...
427
- Router.map(function() {
428
- this.route('blogPost', { path:':blogPostId' }, function() {
429
- this.route('blogComment', { path: ':blogCommentId' });
430
- });
431
- });
432
- export default Router;
433
- ```
434
- ```javascript
435
- this.transitionTo('blogComment', aPost, aComment);
436
- this.transitionTo('blogComment', 1, 13);
437
- ```
438
- It is also possible to pass a URL (a string that starts with a
439
- `/`).
440
- ```javascript
441
- this.transitionTo('/');
442
- this.transitionTo('/blog/post/1/comment/13');
443
- this.transitionTo('/blog/posts?sort=title');
444
- ```
445
- An options hash with a `queryParams` property may be provided as
446
- the final argument to add query parameters to the destination URL.
447
- ```javascript
448
- this.transitionTo('blogPost', 1, {
449
- queryParams: { showComments: 'true' }
450
- });
451
- // if you just want to transition the query parameters without changing the route
452
- this.transitionTo({ queryParams: { sort: 'date' } });
453
- ```
454
- See also [replaceWith](#method_replaceWith).
455
- Simple Transition Example
456
- ```app/routes.js
457
- // ...
458
- Router.map(function() {
459
- this.route('index');
460
- this.route('secret');
461
- this.route('fourOhFour', { path: '*:' });
462
- });
463
- export default Router;
464
- ```
465
- ```app/routes/index.js
466
- import Route from '@ember/routing/route';
467
- import { action } from '@ember/object';
468
- export default class IndexRoute extends Route {
469
- @action
470
- moveToSecret(context) {
471
- if (authorized()) {
472
- this.transitionTo('secret', context);
473
- } else {
474
- this.transitionTo('fourOhFour');
475
- }
476
- }
477
- }
478
- ```
479
- Transition to a nested route
480
- ```app/router.js
481
- // ...
482
- Router.map(function() {
483
- this.route('articles', { path: '/articles' }, function() {
484
- this.route('new');
485
- });
486
- });
487
- export default Router;
488
- ```
489
- ```app/routes/index.js
490
- import Route from '@ember/routing/route';
491
- import { action } from '@ember/object';
492
- export default class IndexRoute extends Route {
493
- @action
494
- transitionToNewArticle() {
495
- this.transitionTo('articles.new');
496
- }
497
- }
498
- ```
499
- Multiple Models Example
500
- ```app/router.js
501
- // ...
502
- Router.map(function() {
503
- this.route('index');
504
- this.route('breakfast', { path: ':breakfastId' }, function() {
505
- this.route('cereal', { path: ':cerealId' });
506
- });
507
- });
508
- export default Router;
509
- ```
510
- ```app/routes/index.js
511
- import Route from '@ember/routing/route';
512
- import { action } from '@ember/object';
513
- export default class IndexRoute extends Route {
514
- @action
515
- moveToChocolateCereal() {
516
- let cereal = { cerealId: 'ChocolateYumminess' };
517
- let breakfast = { breakfastId: 'CerealAndMilk' };
518
- this.transitionTo('breakfast.cereal', breakfast, cereal);
519
- }
520
- }
521
- ```
522
- Nested Route with Query String Example
523
- ```app/routes.js
524
- // ...
525
- Router.map(function() {
526
- this.route('fruits', function() {
527
- this.route('apples');
528
- });
529
- });
530
- export default Router;
531
- ```
532
- ```app/routes/index.js
533
- import Route from '@ember/routing/route';
534
- export default class IndexRoute extends Route {
535
- @action
536
- transitionToApples() {
537
- this.transitionTo('fruits.apples', { queryParams: { color: 'red' } });
538
- }
539
- }
540
- ```
541
- @method transitionTo
542
- @param {String} [name] the name of the route or a URL.
543
- @param {...Object} [models] the model(s) or identifier(s) to be used while
544
- transitioning to the route.
545
- @param {Object} [options] optional hash with a queryParams property
546
- containing a mapping of query parameters. May be supplied as the only
547
- parameter to trigger a query-parameter-only transition.
548
- @return {Transition} the transition object associated with this
549
- attempted transition
550
- @since 1.0.0
551
- @deprecated Use transitionTo from the Router service instead.
552
- @public
553
- */
554
-
555
-
556
- transitionTo(...args) {
557
- deprecateTransitionMethods('route', 'transitionTo');
558
- return this._router.transitionTo(...prefixRouteNameArg(this, args));
559
- }
560
- /**
561
- Perform a synchronous transition into another route without attempting
562
- to resolve promises, update the URL, or abort any currently active
563
- asynchronous transitions (i.e. regular transitions caused by
564
- `transitionTo` or URL changes).
565
- This method is handy for performing intermediate transitions on the
566
- way to a final destination route, and is called internally by the
567
- default implementations of the `error` and `loading` handlers.
568
- @method intermediateTransitionTo
569
- @param {String} name the name of the route
570
- @param {...Object} models the model(s) to be used while transitioning
571
- to the route.
572
- @since 1.2.0
573
- @public
574
- */
575
-
576
-
577
- intermediateTransitionTo(...args) {
578
- let [name, ...preparedArgs] = prefixRouteNameArg(this, args);
579
-
580
- this._router.intermediateTransitionTo(name, ...preparedArgs);
581
- }
582
- /**
583
- Refresh the model on this route and any child routes, firing the
584
- `beforeModel`, `model`, and `afterModel` hooks in a similar fashion
585
- to how routes are entered when transitioning in from other route.
586
- The current route params (e.g. `article_id`) will be passed in
587
- to the respective model hooks, and if a different model is returned,
588
- `setupController` and associated route hooks will re-fire as well.
589
- An example usage of this method is re-querying the server for the
590
- latest information using the same parameters as when the route
591
- was first entered.
592
- Note that this will cause `model` hooks to fire even on routes
593
- that were provided a model object when the route was initially
594
- entered.
595
- @method refresh
596
- @return {Transition} the transition object associated with this
597
- attempted transition
598
- @since 1.4.0
599
- @public
600
- */
601
-
602
-
603
- refresh() {
604
- return this._router._routerMicrolib.refresh(this);
605
- }
606
- /**
607
- Transition into another route while replacing the current URL, if possible.
608
- This will replace the current history entry instead of adding a new one.
609
- Beside that, it is identical to `transitionTo` in all other respects. See
610
- 'transitionTo' for additional information regarding multiple models.
611
- Example
612
- ```app/router.js
613
- // ...
614
- Router.map(function() {
615
- this.route('index');
616
- this.route('secret');
617
- });
618
- export default Router;
619
- ```
620
- ```app/routes/secret.js
621
- import Route from '@ember/routing/route';
622
- export default class SecretRoute Route {
623
- afterModel() {
624
- if (!authorized()){
625
- this.replaceWith('index');
626
- }
627
- }
628
- }
629
- ```
630
- @method replaceWith
631
- @param {String} name the name of the route or a URL
632
- @param {...Object} models the model(s) or identifier(s) to be used while
633
- transitioning to the route.
634
- @param {Object} [options] optional hash with a queryParams property
635
- containing a mapping of query parameters
636
- @return {Transition} the transition object associated with this
637
- attempted transition
638
- @since 1.0.0
639
- @deprecated Use replaceWith from the Router service instead.
640
- @public
641
- */
642
-
643
-
644
- replaceWith(...args) {
645
- deprecateTransitionMethods('route', 'replaceWith');
646
- return this._router.replaceWith(...prefixRouteNameArg(this, args));
647
- }
648
- /**
649
- This hook is the entry point for router.js
650
- @private
651
- @method setup
652
- */
653
-
654
-
655
- setup(context, transition) {
656
- let controllerName = this.controllerName || this.routeName;
657
- let definedController = this.controllerFor(controllerName, true);
658
- let controller = definedController !== null && definedController !== void 0 ? definedController : this.generateController(controllerName); // SAFETY: Since `_qp` is protected we can't infer the type
659
-
660
- let queryParams = get(this, '_qp'); // Assign the route's controller so that it can more easily be
661
- // referenced in action handlers. Side effects. Side effects everywhere.
662
-
663
- if (!this.controller) {
664
- let propNames = queryParams.propertyNames;
665
- addQueryParamsObservers(controller, propNames);
666
- this.controller = controller;
667
- }
668
-
669
- let states = queryParams.states;
670
- controller._qpDelegate = states.allowOverrides;
671
-
672
- if (transition) {
673
- // Update the model dep values used to calculate cache keys.
674
- stashParamNames(this._router, transition[STATE_SYMBOL].routeInfos);
675
- let cache = this._bucketCache;
676
- let params = transition[PARAMS_SYMBOL];
677
- let allParams = queryParams.propertyNames;
678
- allParams.forEach(prop => {
679
- let aQp = queryParams.map[prop];
680
- assert('expected aQp', aQp);
681
- aQp.values = params;
682
- let cacheKey = calculateCacheKey(aQp.route.fullRouteName, aQp.parts, aQp.values);
683
- let value = cache.lookup(cacheKey, prop, aQp.undecoratedDefaultValue);
684
- set(controller, prop, value);
685
- });
686
- let qpValues = getQueryParamsFor(this, transition[STATE_SYMBOL]);
687
- setProperties(controller, qpValues);
688
- }
689
-
690
- this.setupController(controller, context, transition);
691
-
692
- if (this._environment.options.shouldRender) {
693
- this[RENDER]();
694
- } // Setup can cause changes to QPs which need to be propogated immediately in
695
- // some situations. Eventually, we should work on making these async somehow.
696
-
697
-
698
- flushAsyncObservers(false);
699
- }
700
- /*
701
- Called when a query parameter for this route changes, regardless of whether the route
702
- is currently part of the active route hierarchy. This will update the query parameter's
703
- value in the cache so if this route becomes active, the cache value has been updated.
704
- */
705
-
706
-
707
- _qpChanged(prop, value, qp) {
708
- if (!qp) {
709
- return;
710
- } // Update model-dep cache
711
-
712
-
713
- let cache = this._bucketCache;
714
- let cacheKey = calculateCacheKey(qp.route.fullRouteName, qp.parts, qp.values);
715
- cache.stash(cacheKey, prop, value);
716
- }
717
-
718
- beforeModel(_transition) {}
719
-
720
- afterModel(_resolvedModel, _transition) {}
721
- /**
722
- A hook you can implement to optionally redirect to another route.
723
- Calling `this.transitionTo` from inside of the `redirect` hook will
724
- abort the current transition (into the route that has implemented `redirect`).
725
- `redirect` and `afterModel` behave very similarly and are
726
- called almost at the same time, but they have an important
727
- distinction when calling `this.transitionTo` to a child route
728
- of the current route. From `afterModel`, this new transition
729
- invalidates the current transition, causing `beforeModel`,
730
- `model`, and `afterModel` hooks to be called again. But the
731
- same transition started from `redirect` does _not_ invalidate
732
- the current transition. In other words, by the time the `redirect`
733
- hook has been called, both the resolved model and the attempted
734
- entry into this route are considered fully validated.
735
- @method redirect
736
- @param {Object} model the model for this route
737
- @param {Transition} transition the transition object associated with the current transition
738
- @since 1.0.0
739
- @public
740
- */
741
-
742
-
743
- redirect(_model, _transition) {}
744
- /**
745
- Called when the context is changed by router.js.
746
- @private
747
- @method contextDidChange
748
- */
749
-
750
-
751
- contextDidChange() {
752
- this.currentModel = this.context;
753
- }
754
- /**
755
- A hook you can implement to convert the URL into the model for
756
- this route.
757
- ```app/router.js
758
- // ...
759
- Router.map(function() {
760
- this.route('post', { path: '/posts/:post_id' });
761
- });
762
- export default Router;
763
- ```
764
- The model for the `post` route is `store.findRecord('post', params.post_id)`.
765
- By default, if your route has a dynamic segment ending in `_id`:
766
- * The model class is determined from the segment (`post_id`'s
767
- class is `App.Post`)
768
- * The find method is called on the model class with the value of
769
- the dynamic segment.
770
- Note that for routes with dynamic segments, this hook is not always
771
- executed. If the route is entered through a transition (e.g. when
772
- using the `link-to` Handlebars helper or the `transitionTo` method
773
- of routes), and a model context is already provided this hook
774
- is not called.
775
- A model context does not include a primitive string or number,
776
- which does cause the model hook to be called.
777
- Routes without dynamic segments will always execute the model hook.
778
- ```javascript
779
- // no dynamic segment, model hook always called
780
- this.transitionTo('posts');
781
- // model passed in, so model hook not called
782
- thePost = store.findRecord('post', 1);
783
- this.transitionTo('post', thePost);
784
- // integer passed in, model hook is called
785
- this.transitionTo('post', 1);
786
- // model id passed in, model hook is called
787
- // useful for forcing the hook to execute
788
- thePost = store.findRecord('post', 1);
789
- this.transitionTo('post', thePost.id);
790
- ```
791
- This hook follows the asynchronous/promise semantics
792
- described in the documentation for `beforeModel`. In particular,
793
- if a promise returned from `model` fails, the error will be
794
- handled by the `error` hook on `Route`.
795
- Example
796
- ```app/routes/post.js
797
- import Route from '@ember/routing/route';
798
- export default class PostRoute extends Route {
799
- model(params) {
800
- return this.store.findRecord('post', params.post_id);
801
- }
802
- }
803
- ```
804
- @method model
805
- @param {Object} params the parameters extracted from the URL
806
- @param {Transition} transition
807
- @return {any | Promise<any>} the model for this route. If
808
- a promise is returned, the transition will pause until
809
- the promise resolves, and the resolved value of the promise
810
- will be used as the model for this route.
811
- @since 1.0.0
812
- @public
813
- */
814
-
815
-
816
- model(params, transition) {
817
- let name, sawParams, value; // SAFETY: Since `_qp` is protected we can't infer the type
818
-
819
- let queryParams = get(this, '_qp').map;
820
-
821
- for (let prop in params) {
822
- if (prop === 'queryParams' || queryParams && prop in queryParams) {
823
- continue;
824
- }
825
-
826
- let match = prop.match(/^(.*)_id$/);
827
-
828
- if (match !== null) {
829
- name = match[1];
830
- value = params[prop];
831
- }
832
-
833
- sawParams = true;
834
- }
835
-
836
- if (!name) {
837
- if (sawParams) {
838
- // SAFETY: This should be equivalent
839
- return Object.assign({}, params);
840
- } else {
841
- if (transition.resolveIndex < 1) {
842
- return;
843
- } // SAFETY: This should be correct, but TS is unable to infer this.
844
-
845
-
846
- return transition[STATE_SYMBOL].routeInfos[transition.resolveIndex - 1].context;
847
- }
848
- }
849
-
850
- return this.findModel(name, value);
851
- }
852
- /**
853
- @private
854
- @method deserialize
855
- @param {Object} params the parameters extracted from the URL
856
- @param {Transition} transition
857
- @return {any | Promise<any>} the model for this route.
858
- Router.js hook.
859
- */
860
-
861
-
862
- deserialize(_params, transition) {
863
- return this.model(this._paramsFor(this.routeName, _params), transition);
864
- }
865
- /**
866
- @method findModel
867
- @param {String} type the model type
868
- @param {Object} value the value passed to find
869
- @private
870
- */
871
-
872
-
873
- findModel(...args) {
874
- return get(this, 'store').find(...args);
875
- }
876
- /**
877
- A hook you can use to setup the controller for the current route.
878
- This method is called with the controller for the current route and the
879
- model supplied by the `model` hook.
880
- By default, the `setupController` hook sets the `model` property of
881
- the controller to the specified `model` when it is not `undefined`.
882
- If you implement the `setupController` hook in your Route, it will
883
- prevent this default behavior. If you want to preserve that behavior
884
- when implementing your `setupController` function, make sure to call
885
- `super`:
886
- ```app/routes/photos.js
887
- import Route from '@ember/routing/route';
888
- export default class PhotosRoute extends Route {
889
- model() {
890
- return this.store.findAll('photo');
891
- }
892
- setupController(controller, model) {
893
- super.setupController(controller, model);
894
- this.controllerFor('application').set('showingPhotos', true);
895
- }
896
- }
897
- ```
898
- The provided controller will be one resolved based on the name
899
- of this route.
900
- If no explicit controller is defined, Ember will automatically create one.
901
- As an example, consider the router:
902
- ```app/router.js
903
- // ...
904
- Router.map(function() {
905
- this.route('post', { path: '/posts/:post_id' });
906
- });
907
- export default Router;
908
- ```
909
- If you have defined a file for the post controller,
910
- the framework will use it.
911
- If it is not defined, a basic `Controller` instance would be used.
912
- @example Behavior of a basic Controller
913
- ```app/routes/post.js
914
- import Route from '@ember/routing/route';
915
- export default class PostRoute extends Route {
916
- setupController(controller, model) {
917
- controller.set('model', model);
918
- }
919
- });
920
- ```
921
- @method setupController
922
- @param {Controller} controller instance
923
- @param {Object} model
924
- @param {Transition} [transition]
925
- @since 1.0.0
926
- @public
927
- */
928
-
929
-
930
- setupController(controller, context, _transition) {
931
- if (controller && context !== undefined) {
932
- set(controller, 'model', context);
933
- }
934
- }
935
-
936
- controllerFor(name, _skipAssert = false) {
937
- let owner = getOwner(this);
938
- assert('Route is unexpectedly missing an owner', owner);
939
- let route = owner.lookup(`route:${name}`);
940
-
941
- if (route && route.controllerName) {
942
- name = route.controllerName;
943
- }
944
-
945
- let controller = owner.lookup(`controller:${name}`); // NOTE: We're specifically checking that skipAssert is true, because according
946
- // to the old API the second parameter was model. We do not want people who
947
- // passed a model to skip the assertion.
948
-
949
- assert(`The controller named '${name}' could not be found. Make sure that this route exists and has already been entered at least once. If you are accessing a controller not associated with a route, make sure the controller class is explicitly defined.`, controller !== undefined || _skipAssert === true);
950
- assert(`Expected controller:${name} to be an instance of Controller`, controller === undefined || controller instanceof Controller);
951
- return controller;
952
- }
953
- /**
954
- Generates a controller for a route.
955
- Example
956
- ```app/routes/post.js
957
- import Route from '@ember/routing/route';
958
- export default class Post extends Route {
959
- setupController(controller, post) {
960
- super.setupController(controller, post);
961
- this.generateController('posts');
962
- }
963
- }
964
- ```
965
- @method generateController
966
- @param {String} name the name of the controller
967
- @private
968
- */
969
-
970
-
971
- generateController(name) {
972
- let owner = getOwner(this);
973
- assert('Route is unexpectedly missing an owner', owner);
974
- return generateController(owner, name);
975
- }
976
- /**
977
- Returns the resolved model of a parent (or any ancestor) route
978
- in a route hierarchy. During a transition, all routes
979
- must resolve a model object, and if a route
980
- needs access to a parent route's model in order to
981
- resolve a model (or just reuse the model from a parent),
982
- it can call `this.modelFor(theNameOfParentRoute)` to
983
- retrieve it. If the ancestor route's model was a promise,
984
- its resolved result is returned.
985
- Example
986
- ```app/router.js
987
- // ...
988
- Router.map(function() {
989
- this.route('post', { path: '/posts/:post_id' }, function() {
990
- this.route('comments');
991
- });
992
- });
993
- export default Router;
994
- ```
995
- ```app/routes/post/comments.js
996
- import Route from '@ember/routing/route';
997
- export default class PostCommentsRoute extends Route {
998
- model() {
999
- let post = this.modelFor('post');
1000
- return post.comments;
1001
- }
1002
- }
1003
- ```
1004
- @method modelFor
1005
- @param {String} name the name of the route
1006
- @return {Object} the model object
1007
- @since 1.0.0
1008
- @public
1009
- */
1010
-
1011
-
1012
- modelFor(_name) {
1013
- let name;
1014
- let owner = getOwner(this);
1015
- assert('Expected router owner to be an EngineInstance', owner instanceof EngineInstance);
1016
- let transition = this._router && this._router._routerMicrolib ? this._router._routerMicrolib.activeTransition : undefined; // Only change the route name when there is an active transition.
1017
- // Otherwise, use the passed in route name.
1018
-
1019
- if (owner.routable && transition !== undefined) {
1020
- name = getEngineRouteName(owner, _name);
1021
- } else {
1022
- name = _name;
1023
- }
1024
-
1025
- let route = owner.lookup(`route:${name}`); // If we are mid-transition, we want to try and look up
1026
- // resolved parent contexts on the current transitionEvent.
1027
-
1028
- if (transition !== undefined && transition !== null) {
1029
- let modelLookupName = route && route.routeName || name;
1030
-
1031
- if (Object.prototype.hasOwnProperty.call(transition.resolvedModels, modelLookupName)) {
1032
- return transition.resolvedModels[modelLookupName];
1033
- }
1034
- }
1035
-
1036
- return route === null || route === void 0 ? void 0 : route.currentModel;
1037
- }
1038
- /**
1039
- `this[RENDER]` is used to render a template into a region of another template
1040
- (indicated by an `{{outlet}}`).
1041
- @method this[RENDER]
1042
- @param {String} name the name of the template to render
1043
- @param {Object} [options] the options
1044
- @param {String} [options.into] the template to render into,
1045
- referenced by name. Defaults to the parent template
1046
- @param {String} [options.outlet] the outlet inside `options.into` to render into.
1047
- Defaults to 'main'
1048
- @param {String|Object} [options.controller] the controller to use for this template,
1049
- referenced by name or as a controller instance. Defaults to the Route's paired controller
1050
- @param {Object} [options.model] the model object to set on `options.controller`.
1051
- Defaults to the return value of the Route's model hook
1052
- @private
1053
- */
1054
-
1055
-
1056
- [RENDER](name, options) {
1057
- let renderOptions = buildRenderOptions(this, name, options);
1058
- ROUTE_CONNECTIONS.get(this).push(renderOptions);
1059
- once(this._router, '_setOutlets');
1060
- }
1061
-
1062
- willDestroy() {
1063
- this.teardownViews();
1064
- }
1065
- /**
1066
- @private
1067
- @method teardownViews
1068
- */
1069
-
1070
-
1071
- teardownViews() {
1072
- let connections = ROUTE_CONNECTIONS.get(this);
1073
-
1074
- if (connections !== undefined && connections.length > 0) {
1075
- ROUTE_CONNECTIONS.set(this, []);
1076
- once(this._router, '_setOutlets');
1077
- }
1078
- }
1079
-
1080
- buildRouteInfoMetadata() {}
1081
-
1082
- _paramsFor(routeName, params) {
1083
- let transition = this._router._routerMicrolib.activeTransition;
1084
-
1085
- if (transition !== undefined) {
1086
- return this.paramsFor(routeName);
1087
- }
1088
-
1089
- return params;
1090
- }
1091
- /**
1092
- Store property provides a hook for data persistence libraries to inject themselves.
1093
- By default, this store property provides the exact same functionality previously
1094
- in the model hook.
1095
- Currently, the required interface is:
1096
- `store.find(modelName, findArguments)`
1097
- @property store
1098
- @type {Object}
1099
- @private
1100
- */
1101
-
1102
-
1103
- get store() {
1104
- const owner = getOwner(this);
1105
- assert('Route is unexpectedly missing an owner', owner);
1106
- let routeName = this.routeName;
1107
- return {
1108
- find(name, value) {
1109
- let modelClass = owner.factoryFor(`model:${name}`);
1110
- assert(`You used the dynamic segment \`${name}_id\` in your route ` + `\`${routeName}\` for which Ember requires you provide a ` + `data-loading implementation. Commonly, that is done by ` + `adding a model hook implementation on the route ` + `(\`model({${name}_id}) {\`) or by injecting an implemention of ` + `a data store: \`@service store;\`.`, Boolean(modelClass));
1111
-
1112
- if (!modelClass) {
1113
- return;
1114
- }
1115
-
1116
- modelClass = modelClass.class;
1117
- assert(`You used the dynamic segment \`${name}_id\` in your route ` + `\`${routeName}\` for which Ember requires you provide a ` + `data-loading implementation. Commonly, that is done by ` + `adding a model hook implementation on the route ` + `(\`model({${name}_id}) {\`) or by injecting an implemention of ` + `a data store: \`@service store;\`.\n\n` + `Rarely, applications may attempt to use a legacy behavior where ` + `the model class (in this case \`${name}\`) is resolved and the ` + `\`find\` method on that class is invoked to load data. In this ` + `application, a model of \`${name}\` was found but it did not ` + `provide a \`find\` method. You should not add a \`find\` ` + `method to your model. Instead, please implement an appropriate ` + `\`model\` hook on the \`${routeName}\` route.`, typeof modelClass.find === 'function');
1118
- return modelClass.find(value);
1119
- }
1120
-
1121
- };
1122
- }
1123
-
1124
- set store(value) {
1125
- defineProperty(this, 'store', null, value);
1126
- }
1127
- /**
1128
- @private
1129
- @property _qp
1130
- */
1131
-
1132
-
1133
- get _qp() {
1134
- let combinedQueryParameterConfiguration = {};
1135
- let controllerName = this.controllerName || this.routeName;
1136
- let owner = getOwner(this);
1137
- assert('Route is unexpectedly missing an owner', owner);
1138
- let controller = owner.lookup(`controller:${controllerName}`);
1139
- let queryParameterConfiguraton = get(this, 'queryParams');
1140
- let hasRouterDefinedQueryParams = Object.keys(queryParameterConfiguraton).length > 0;
1141
-
1142
- if (controller) {
1143
- assert('Expected an instance of controller', controller instanceof Controller); // the developer has authored a controller class in their application for
1144
- // this route find its query params and normalize their object shape them
1145
- // merge in the query params for the route. As a mergedProperty,
1146
- // Route#queryParams is always at least `{}`
1147
-
1148
- let controllerDefinedQueryParameterConfiguration = get(controller, 'queryParams') || [];
1149
- let normalizedControllerQueryParameterConfiguration = normalizeControllerQueryParams(controllerDefinedQueryParameterConfiguration);
1150
- combinedQueryParameterConfiguration = mergeEachQueryParams(normalizedControllerQueryParameterConfiguration, queryParameterConfiguraton);
1151
- } else if (hasRouterDefinedQueryParams) {
1152
- // the developer has not defined a controller but *has* supplied route query params.
1153
- // Generate a class for them so we can later insert default values
1154
- controller = generateController(owner, controllerName);
1155
- combinedQueryParameterConfiguration = queryParameterConfiguraton;
1156
- }
1157
-
1158
- let qps = [];
1159
- let map = {};
1160
- let propertyNames = [];
1161
-
1162
- for (let propName in combinedQueryParameterConfiguration) {
1163
- if (!Object.prototype.hasOwnProperty.call(combinedQueryParameterConfiguration, propName)) {
1164
- continue;
1165
- } // to support the dubious feature of using unknownProperty
1166
- // on queryParams configuration
1167
-
1168
-
1169
- if (propName === 'unknownProperty' || propName === '_super') {
1170
- // possible todo: issue deprecation warning?
1171
- continue;
1172
- }
1173
-
1174
- let desc = combinedQueryParameterConfiguration[propName];
1175
- assert(`[BUG] missing query parameter configuration for ${propName}`, desc);
1176
- let scope = desc.scope || 'model';
1177
- let parts = undefined;
1178
-
1179
- if (scope === 'controller') {
1180
- parts = [];
1181
- }
1182
-
1183
- let urlKey = desc.as || this.serializeQueryParamKey(propName);
1184
- let defaultValue = get(controller, propName);
1185
- defaultValue = copyDefaultValue(defaultValue);
1186
- let type = desc.type || typeOf(defaultValue);
1187
- let defaultValueSerialized = this.serializeQueryParam(defaultValue, urlKey, type);
1188
- let scopedPropertyName = `${controllerName}:${propName}`;
1189
- let qp = {
1190
- undecoratedDefaultValue: get(controller, propName),
1191
- defaultValue,
1192
- serializedDefaultValue: defaultValueSerialized,
1193
- serializedValue: defaultValueSerialized,
1194
- type,
1195
- urlKey,
1196
- prop: propName,
1197
- scopedPropertyName,
1198
- controllerName,
1199
- route: this,
1200
- parts,
1201
- values: null,
1202
- scope
1203
- };
1204
- map[propName] = map[urlKey] = map[scopedPropertyName] = qp;
1205
- qps.push(qp);
1206
- propertyNames.push(propName);
1207
- }
1208
-
1209
- return {
1210
- qps,
1211
- map,
1212
- propertyNames,
1213
- states: {
1214
- /*
1215
- Called when a query parameter changes in the URL, this route cares
1216
- about that query parameter, but the route is not currently
1217
- in the active route hierarchy.
1218
- */
1219
- inactive: (prop, value) => {
1220
- let qp = map[prop];
1221
- assert('expected inactive callback to only be called for registered qps', qp);
1222
-
1223
- this._qpChanged(prop, value, qp);
1224
- },
1225
-
1226
- /*
1227
- Called when a query parameter changes in the URL, this route cares
1228
- about that query parameter, and the route is currently
1229
- in the active route hierarchy.
1230
- */
1231
- active: (prop, value) => {
1232
- let qp = map[prop];
1233
- assert('expected active callback to only be called for registered qps', qp);
1234
-
1235
- this._qpChanged(prop, value, qp);
1236
-
1237
- return this._activeQPChanged(qp, value);
1238
- },
1239
-
1240
- /*
1241
- Called when a value of a query parameter this route handles changes in a controller
1242
- and the route is currently in the active route hierarchy.
1243
- */
1244
- allowOverrides: (prop, value) => {
1245
- let qp = map[prop];
1246
- assert('expected allowOverrides callback to only be called for registered qps', qp);
1247
-
1248
- this._qpChanged(prop, value, qp);
1249
-
1250
- return this._updatingQPChanged(qp);
1251
- }
1252
- }
1253
- };
1254
- }
1255
-
1256
- }
1257
-
1258
- Route.isRouteFactory = true;
1259
-
1260
- __decorate([computed], Route.prototype, "store", null);
1261
-
1262
- __decorate([computed], Route.prototype, "_qp", null);
1263
-
1264
- function parentRoute(route) {
1265
- let routeInfo = routeInfoFor(route, route._router._routerMicrolib.state.routeInfos, -1);
1266
- return routeInfo && routeInfo.route;
1267
- }
1268
-
1269
- function routeInfoFor(route, routeInfos, offset = 0) {
1270
- if (!routeInfos) {
1271
- return;
1272
- }
1273
-
1274
- let current;
1275
-
1276
- for (let i = 0; i < routeInfos.length; i++) {
1277
- let routeInfo = routeInfos[i];
1278
- assert('has current routeInfo', routeInfo);
1279
- current = routeInfo.route;
1280
-
1281
- if (current === route) {
1282
- return routeInfos[i + offset];
1283
- }
1284
- }
1285
-
1286
- return;
1287
- }
1288
-
1289
- function buildRenderOptions(route, nameOrOptions, options) {
1290
- let isDefaultRender = !nameOrOptions && !options;
1291
-
1292
- let _name;
1293
-
1294
- if (!isDefaultRender) {
1295
- if (typeof nameOrOptions === 'object' && !options) {
1296
- _name = route.templateName || route.routeName;
1297
- options = nameOrOptions;
1298
- } else {
1299
- assert('The name in the given arguments is undefined or empty string', !isEmpty(nameOrOptions));
1300
- _name = nameOrOptions;
1301
- }
1302
- }
1303
-
1304
- assert('You passed undefined as the outlet name.', isDefaultRender || !(options && 'outlet' in options && options.outlet === undefined));
1305
- let owner = getOwner(route);
1306
- assert('Route is unexpectedly missing an owner', owner);
1307
- let name, templateName, into, outlet, model;
1308
- let controller;
1309
-
1310
- if (options) {
1311
- into = options.into && options.into.replace(/\//g, '.');
1312
- outlet = options.outlet;
1313
- controller = options.controller;
1314
- model = options.model;
1315
- }
1316
-
1317
- outlet = outlet || 'main';
1318
-
1319
- if (isDefaultRender) {
1320
- name = route.routeName;
1321
- templateName = route.templateName || name;
1322
- } else {
1323
- name = _name.replace(/\//g, '.');
1324
- templateName = name;
1325
- }
1326
-
1327
- if (controller === undefined) {
1328
- if (isDefaultRender) {
1329
- controller = route.controllerName || owner.lookup(`controller:${name}`);
1330
- } else {
1331
- controller = owner.lookup(`controller:${name}`) || route.controllerName || route.routeName;
1332
- }
1333
- }
1334
-
1335
- if (typeof controller === 'string') {
1336
- let controllerName = controller;
1337
- controller = owner.lookup(`controller:${controllerName}`);
1338
- assert(`You passed \`controller: '${controllerName}'\` into the \`render\` method, but no such controller could be found.`, isDefaultRender || controller !== undefined);
1339
- }
1340
-
1341
- assert('Expected an instance of controller', controller instanceof Controller);
1342
-
1343
- if (model === undefined) {
1344
- model = route.currentModel;
1345
- } else {
1346
- controller.set('model', model);
1347
- }
1348
-
1349
- let template = owner.lookup(`template:${templateName}`);
1350
- assert(`Could not find "${templateName}" template, view, or component.`, isDefaultRender || template !== undefined);
1351
- let parent;
1352
-
1353
- if (into && (parent = parentRoute(route)) && into === parent.routeName) {
1354
- into = undefined;
1355
- }
1356
-
1357
- let renderOptions = {
1358
- owner,
1359
- into,
1360
- outlet,
1361
- name,
1362
- controller,
1363
- model,
1364
- template: template !== undefined ? template(owner) : route._topLevelViewTemplate(owner)
1365
- };
1366
-
1367
- if (DEBUG) {
1368
- let LOG_VIEW_LOOKUPS = get(route._router, 'namespace.LOG_VIEW_LOOKUPS');
1369
-
1370
- if (LOG_VIEW_LOOKUPS && !template) {
1371
- info(`Could not find "${name}" template. Nothing will be rendered`, {
1372
- fullName: `template:${name}`
1373
- });
1374
- }
1375
- }
1376
-
1377
- return renderOptions;
1378
- }
1379
-
1380
- export function getFullQueryParams(router, state) {
1381
- if (state.fullQueryParams) {
1382
- return state.fullQueryParams;
1383
- }
1384
-
1385
- let haveAllRouteInfosResolved = state.routeInfos.every(routeInfo => routeInfo.route);
1386
- let fullQueryParamsState = Object.assign({}, state.queryParams);
1387
-
1388
- router._deserializeQueryParams(state.routeInfos, fullQueryParamsState); // only cache query params state if all routeinfos have resolved; it's possible
1389
- // for lazy routes to not have resolved when `getFullQueryParams` is called, so
1390
- // we wait until all routes have resolved prior to caching query params state
1391
-
1392
-
1393
- if (haveAllRouteInfosResolved) {
1394
- state.fullQueryParams = fullQueryParamsState;
1395
- }
1396
-
1397
- return fullQueryParamsState;
1398
- }
1399
-
1400
- function getQueryParamsFor(route, state) {
1401
- state.queryParamsFor = state.queryParamsFor || {};
1402
- let name = route.fullRouteName;
1403
- let existing = state.queryParamsFor[name];
1404
-
1405
- if (existing) {
1406
- return existing;
1407
- }
1408
-
1409
- let fullQueryParams = getFullQueryParams(route._router, state);
1410
- let params = state.queryParamsFor[name] = {}; // Copy over all the query params for this route/controller into params hash.
1411
- // SAFETY: Since `_qp` is protected we can't infer the type
1412
-
1413
- let qps = get(route, '_qp').qps;
1414
-
1415
- for (let qp of qps) {
1416
- // Put deserialized qp on params hash.
1417
- let qpValueWasPassedIn = (qp.prop in fullQueryParams);
1418
- params[qp.prop] = qpValueWasPassedIn ? fullQueryParams[qp.prop] : copyDefaultValue(qp.defaultValue);
1419
- }
1420
-
1421
- return params;
1422
- } // FIXME: This should probably actually return a `NativeArray` if the passed in value is an Array.
1423
-
1424
-
1425
- function copyDefaultValue(value) {
1426
- if (Array.isArray(value)) {
1427
- // SAFETY: We lost the type data about the array if we don't cast.
1428
- return emberA(value.slice());
1429
- }
1430
-
1431
- return value;
1432
- }
1433
- /*
1434
- Merges all query parameters from a controller with those from
1435
- a route, returning a new object and avoiding any mutations to
1436
- the existing objects.
1437
- */
1438
-
1439
-
1440
- function mergeEachQueryParams(controllerQP, routeQP) {
1441
- let qps = {};
1442
- let keysAlreadyMergedOrSkippable = {
1443
- defaultValue: true,
1444
- type: true,
1445
- scope: true,
1446
- as: true
1447
- }; // first loop over all controller qps, merging them with any matching route qps
1448
- // into a new empty object to avoid mutating.
1449
-
1450
- for (let cqpName in controllerQP) {
1451
- if (!Object.prototype.hasOwnProperty.call(controllerQP, cqpName)) {
1452
- continue;
1453
- }
1454
-
1455
- qps[cqpName] = Object.assign(Object.assign({}, controllerQP[cqpName]), routeQP[cqpName]); // allows us to skip this QP when we check route QPs.
1456
-
1457
- keysAlreadyMergedOrSkippable[cqpName] = true;
1458
- } // loop over all route qps, skipping those that were merged in the first pass
1459
- // because they also appear in controller qps
1460
-
1461
-
1462
- for (let rqpName in routeQP) {
1463
- if (!Object.prototype.hasOwnProperty.call(routeQP, rqpName) || keysAlreadyMergedOrSkippable[rqpName]) {
1464
- continue;
1465
- }
1466
-
1467
- qps[rqpName] = Object.assign(Object.assign({}, routeQP[rqpName]), controllerQP[rqpName]);
1468
- }
1469
-
1470
- return qps;
1471
- }
1472
-
1473
- function addQueryParamsObservers(controller, propNames) {
1474
- propNames.forEach(prop => {
1475
- if (descriptorForProperty(controller, prop) === undefined) {
1476
- let desc = lookupDescriptor(controller, prop);
1477
-
1478
- if (desc !== null && (typeof desc.get === 'function' || typeof desc.set === 'function')) {
1479
- defineProperty(controller, prop, dependentKeyCompat({
1480
- get: desc.get,
1481
- set: desc.set
1482
- }));
1483
- }
1484
- }
1485
-
1486
- addObserver(controller, `${prop}.[]`, controller, controller._qpChanged, false);
1487
- });
1488
- }
1489
-
1490
- function getEngineRouteName(engine, routeName) {
1491
- if (engine.routable) {
1492
- let prefix = engine.mountPoint;
1493
-
1494
- if (routeName === 'application') {
1495
- return prefix;
1496
- } else {
1497
- return `${prefix}.${routeName}`;
1498
- }
1499
- }
1500
-
1501
- return routeName;
1502
- }
1503
-
1504
- const defaultSerialize = Route.prototype.serialize;
1505
- export { defaultSerialize };
1506
- export function hasDefaultSerialize(route) {
1507
- return route.serialize === defaultSerialize;
1508
- } // Set these here so they can be overridden with extend
1509
-
1510
- Route.reopen({
1511
- mergedProperties: ['queryParams'],
1512
- queryParams: {},
1513
- templateName: null,
1514
- controllerName: null,
1515
-
1516
- send(...args) {
1517
- assert(`Attempted to call .send() with the action '${args[0]}' on the destroyed route '${this.routeName}'.`, !this.isDestroying && !this.isDestroyed);
1518
-
1519
- if (this._router && this._router._routerMicrolib || !isTesting()) {
1520
- this._router.send(...args);
1521
- } else {
1522
- let name = args.shift();
1523
- let action = this.actions[name];
1524
-
1525
- if (action) {
1526
- return action.apply(this, args);
1527
- }
1528
- }
1529
- },
1530
-
1531
- /**
1532
- The controller associated with this route.
1533
- Example
1534
- ```app/routes/form.js
1535
- import Route from '@ember/routing/route';
1536
- import { action } from '@ember/object';
1537
- export default class FormRoute extends Route {
1538
- @action
1539
- willTransition(transition) {
1540
- if (this.controller.get('userHasEnteredData') &&
1541
- !confirm('Are you sure you want to abandon progress?')) {
1542
- transition.abort();
1543
- } else {
1544
- // Bubble the `willTransition` action so that
1545
- // parent routes can decide whether or not to abort.
1546
- return true;
1547
- }
1548
- }
1549
- }
1550
- ```
1551
- @property controller
1552
- @type Controller
1553
- @since 1.6.0
1554
- @public
1555
- */
1556
- actions: {
1557
- /**
1558
- This action is called when one or more query params have changed. Bubbles.
1559
- @method queryParamsDidChange
1560
- @param changed {Object} Keys are names of query params that have changed.
1561
- @param totalPresent {Object} Keys are names of query params that are currently set.
1562
- @param removed {Object} Keys are names of query params that have been removed.
1563
- @returns {boolean}
1564
- @private
1565
- */
1566
- queryParamsDidChange(changed, _totalPresent, removed) {
1567
- // SAFETY: Since `_qp` is protected we can't infer the type
1568
- let qpMap = get(this, '_qp').map;
1569
- let totalChanged = Object.keys(changed).concat(Object.keys(removed));
1570
-
1571
- for (let change of totalChanged) {
1572
- let qp = qpMap[change];
1573
-
1574
- if (qp) {
1575
- let options = this._optionsForQueryParam(qp);
1576
-
1577
- assert('options exists', options && typeof options === 'object');
1578
-
1579
- if (get(options, 'refreshModel') && this._router.currentState) {
1580
- this.refresh();
1581
- break;
1582
- }
1583
- }
1584
- }
1585
-
1586
- return true;
1587
- },
1588
-
1589
- finalizeQueryParamChange(params, finalParams, transition) {
1590
- if (this.fullRouteName !== 'application') {
1591
- return true;
1592
- } // Transition object is absent for intermediate transitions.
1593
-
1594
-
1595
- if (!transition) {
1596
- return;
1597
- }
1598
-
1599
- let routeInfos = transition[STATE_SYMBOL].routeInfos;
1600
- let router = this._router;
1601
-
1602
- let qpMeta = router._queryParamsFor(routeInfos);
1603
-
1604
- let changes = router._qpUpdates;
1605
- let qpUpdated = false;
1606
- let replaceUrl;
1607
- stashParamNames(router, routeInfos);
1608
-
1609
- for (let qp of qpMeta.qps) {
1610
- let route = qp.route;
1611
- let controller = route.controller;
1612
- let presentKey = qp.urlKey in params && qp.urlKey; // Do a reverse lookup to see if the changed query
1613
- // param URL key corresponds to a QP property on
1614
- // this controller.
1615
-
1616
- let value;
1617
- let svalue;
1618
-
1619
- if (changes.has(qp.urlKey)) {
1620
- // Value updated in/before setupController
1621
- value = get(controller, qp.prop);
1622
- svalue = route.serializeQueryParam(value, qp.urlKey, qp.type);
1623
- } else {
1624
- if (presentKey) {
1625
- svalue = params[presentKey];
1626
-
1627
- if (svalue !== undefined) {
1628
- value = route.deserializeQueryParam(svalue, qp.urlKey, qp.type);
1629
- }
1630
- } else {
1631
- // No QP provided; use default value.
1632
- svalue = qp.serializedDefaultValue;
1633
- value = copyDefaultValue(qp.defaultValue);
1634
- }
1635
- } // SAFETY: Since `_qp` is protected we can't infer the type
1636
-
1637
-
1638
- controller._qpDelegate = get(route, '_qp').states.inactive;
1639
- let thisQueryParamChanged = svalue !== qp.serializedValue;
1640
-
1641
- if (thisQueryParamChanged) {
1642
- if (transition.queryParamsOnly && replaceUrl !== false) {
1643
- let options = route._optionsForQueryParam(qp);
1644
-
1645
- let replaceConfigValue = get(options, 'replace');
1646
-
1647
- if (replaceConfigValue) {
1648
- replaceUrl = true;
1649
- } else if (replaceConfigValue === false) {
1650
- // Explicit pushState wins over any other replaceStates.
1651
- replaceUrl = false;
1652
- }
1653
- }
1654
-
1655
- set(controller, qp.prop, value);
1656
- qpUpdated = true;
1657
- } // Stash current serialized value of controller.
1658
-
1659
-
1660
- qp.serializedValue = svalue;
1661
- let thisQueryParamHasDefaultValue = qp.serializedDefaultValue === svalue;
1662
-
1663
- if (!thisQueryParamHasDefaultValue) {
1664
- finalParams.push({
1665
- value: svalue,
1666
- visible: true,
1667
- key: presentKey || qp.urlKey
1668
- });
1669
- }
1670
- } // Some QPs have been updated, and those changes need to be propogated
1671
- // immediately. Eventually, we should work on making this async somehow.
1672
-
1673
-
1674
- if (qpUpdated === true) {
1675
- flushAsyncObservers(false);
1676
- }
1677
-
1678
- if (replaceUrl) {
1679
- transition.method('replace');
1680
- }
1681
-
1682
- qpMeta.qps.forEach(qp => {
1683
- // SAFETY: Since `_qp` is protected we can't infer the type
1684
- let routeQpMeta = get(qp.route, '_qp');
1685
- let finalizedController = qp.route.controller;
1686
- finalizedController['_qpDelegate'] = get(routeQpMeta, 'states.active');
1687
- });
1688
-
1689
- router._qpUpdates.clear();
1690
-
1691
- return;
1692
- }
1693
-
1694
- }
1695
- });
1696
- export default Route;