ember-source 4.3.0-alpha.4 → 4.3.0
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.
- package/CHANGELOG.md +8 -2
- package/build-metadata.json +3 -3
- package/dist/dependencies/router_js.js +66 -31
- package/dist/ember-template-compiler.js +16 -13
- package/dist/ember-template-compiler.map +1 -1
- package/dist/ember-testing.js +1 -1
- package/dist/ember-testing.map +1 -1
- package/dist/ember.debug.js +685 -1223
- package/dist/ember.debug.map +1 -1
- package/dist/header/license.js +1 -1
- package/dist/packages/@ember/-internals/container/index.js +15 -20
- package/dist/packages/@ember/-internals/glimmer/index.js +60 -45
- package/dist/packages/@ember/-internals/meta/lib/meta.js +8 -9
- package/dist/packages/@ember/-internals/metal/index.js +44 -45
- package/dist/packages/@ember/-internals/routing/lib/ext/controller.js +10 -8
- package/dist/packages/@ember/-internals/routing/lib/services/router.js +165 -197
- package/dist/packages/@ember/-internals/routing/lib/system/route-info.js +2 -2
- package/dist/packages/@ember/-internals/routing/lib/system/route.js +96 -375
- package/dist/packages/@ember/-internals/routing/lib/system/router.js +62 -35
- package/dist/packages/@ember/-internals/routing/lib/utils.js +31 -20
- package/dist/packages/@ember/-internals/runtime/lib/mixins/action_handler.js +32 -32
- package/dist/packages/@ember/-internals/utils/index.js +2 -0
- package/dist/packages/@ember/-internals/views/lib/system/utils.js +1 -0
- package/dist/packages/@ember/canary-features/index.js +2 -2
- package/dist/packages/@ember/controller/index.js +3 -54
- package/dist/packages/@ember/instrumentation/index.js +9 -13
- package/dist/packages/@ember/routing/router-service.js +1 -0
- package/dist/packages/@ember/service/index.js +6 -73
- package/dist/packages/ember/version.js +1 -1
- package/docs/data.json +411 -343
- package/package.json +5 -8
|
@@ -11,6 +11,10 @@ import { calculateCacheKey, extractRouteArgs, getActiveTargetName, resemblesURL
|
|
|
11
11
|
import DSL from './dsl';
|
|
12
12
|
import { defaultSerialize, getFullQueryParams, hasDefaultSerialize, ROUTE_CONNECTIONS } from './route';
|
|
13
13
|
import RouterState from './router_state';
|
|
14
|
+
/**
|
|
15
|
+
@module @ember/routing
|
|
16
|
+
*/
|
|
17
|
+
|
|
14
18
|
import Router, { logAbort, STATE_SYMBOL } from 'router_js';
|
|
15
19
|
|
|
16
20
|
function defaultDidTransition(infos) {
|
|
@@ -166,7 +170,9 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
166
170
|
let name, nameParts, oldNameParts;
|
|
167
171
|
|
|
168
172
|
for (let i = 1; i < routeInfos.length; i++) {
|
|
169
|
-
|
|
173
|
+
let routeInfo = routeInfos[i];
|
|
174
|
+
assert('has routeInfo', routeInfo);
|
|
175
|
+
name = routeInfo.name;
|
|
170
176
|
nameParts = name.split('.');
|
|
171
177
|
oldNameParts = slice.call(path);
|
|
172
178
|
|
|
@@ -472,8 +478,8 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
472
478
|
let defaultParentState;
|
|
473
479
|
let liveRoutes = null;
|
|
474
480
|
|
|
475
|
-
for (let
|
|
476
|
-
let route =
|
|
481
|
+
for (let routeInfo of routeInfos) {
|
|
482
|
+
let route = routeInfo.route;
|
|
477
483
|
let connections = ROUTE_CONNECTIONS.get(route);
|
|
478
484
|
let ownState;
|
|
479
485
|
|
|
@@ -549,9 +555,8 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
549
555
|
/**
|
|
550
556
|
Transition the application into another route. The route may
|
|
551
557
|
be either a single route or route path:
|
|
552
|
-
See [transitionTo](/ember/release/classes/Route/methods/transitionTo?anchor=transitionTo) for more info.
|
|
553
558
|
@method transitionTo
|
|
554
|
-
@param {String} name the name of the route or a URL
|
|
559
|
+
@param {String} [name] the name of the route or a URL
|
|
555
560
|
@param {...Object} models the model(s) or identifier(s) to be used while
|
|
556
561
|
transitioning to the route.
|
|
557
562
|
@param {Object} [options] optional hash with a queryParams property
|
|
@@ -592,6 +597,23 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
592
597
|
}
|
|
593
598
|
}
|
|
594
599
|
}
|
|
600
|
+
/**
|
|
601
|
+
Similar to `transitionTo`, but instead of adding the destination to the browser's URL history,
|
|
602
|
+
it replaces the entry for the current route.
|
|
603
|
+
When the user clicks the "back" button in the browser, there will be fewer steps.
|
|
604
|
+
This is most commonly used to manage redirects in a way that does not cause confusing additions
|
|
605
|
+
to the user's browsing history.
|
|
606
|
+
@method replaceWith
|
|
607
|
+
@param {String} [name] the name of the route or a URL
|
|
608
|
+
@param {...Object} models the model(s) or identifier(s) to be used while
|
|
609
|
+
transitioning to the route.
|
|
610
|
+
@param {Object} [options] optional hash with a queryParams property
|
|
611
|
+
containing a mapping of query parameters
|
|
612
|
+
@return {Transition} the transition object associated with this
|
|
613
|
+
attempted transition
|
|
614
|
+
@public
|
|
615
|
+
*/
|
|
616
|
+
|
|
595
617
|
|
|
596
618
|
replaceWith(...args) {
|
|
597
619
|
return this.transitionTo(...args).method('replace');
|
|
@@ -677,8 +699,11 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
677
699
|
let instances = this._engineInstances;
|
|
678
700
|
|
|
679
701
|
for (let name in instances) {
|
|
680
|
-
|
|
681
|
-
|
|
702
|
+
let instance = instances[name];
|
|
703
|
+
assert('has instance', instance);
|
|
704
|
+
|
|
705
|
+
for (let id in instance) {
|
|
706
|
+
run(instance[id], 'destroy');
|
|
682
707
|
}
|
|
683
708
|
}
|
|
684
709
|
}
|
|
@@ -891,7 +916,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
891
916
|
}
|
|
892
917
|
}
|
|
893
918
|
|
|
894
|
-
_doTransition(_targetRouteName, models, _queryParams,
|
|
919
|
+
_doTransition(_targetRouteName, models, _queryParams, _fromRouterService) {
|
|
895
920
|
let targetRouteName = _targetRouteName || getActiveTargetName(this._routerMicrolib);
|
|
896
921
|
|
|
897
922
|
assert(`The route ${targetRouteName} was not found`, Boolean(targetRouteName) && this._routerMicrolib.hasRoute(targetRouteName));
|
|
@@ -902,7 +927,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
902
927
|
|
|
903
928
|
Object.assign(queryParams, _queryParams);
|
|
904
929
|
|
|
905
|
-
this._prepareQueryParams(targetRouteName, models, queryParams, Boolean(
|
|
930
|
+
this._prepareQueryParams(targetRouteName, models, queryParams, Boolean(_fromRouterService));
|
|
906
931
|
|
|
907
932
|
let transition = this._routerMicrolib.transitionTo(targetRouteName, ...models, {
|
|
908
933
|
queryParams
|
|
@@ -1000,12 +1025,11 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1000
1025
|
let qps = [];
|
|
1001
1026
|
let qpsByUrlKey = DEBUG ? {} : null;
|
|
1002
1027
|
let qpMeta;
|
|
1003
|
-
let qp;
|
|
1004
1028
|
let urlKey;
|
|
1005
1029
|
let qpOther;
|
|
1006
1030
|
|
|
1007
|
-
for (let
|
|
1008
|
-
qpMeta = this._getQPMeta(
|
|
1031
|
+
for (let routeInfo of routeInfos) {
|
|
1032
|
+
qpMeta = this._getQPMeta(routeInfo);
|
|
1009
1033
|
|
|
1010
1034
|
if (!qpMeta) {
|
|
1011
1035
|
shouldCache = false;
|
|
@@ -1013,9 +1037,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1013
1037
|
} // Loop over each QP to make sure we don't have any collisions by urlKey
|
|
1014
1038
|
|
|
1015
1039
|
|
|
1016
|
-
for (let
|
|
1017
|
-
qp = qpMeta.qps[i];
|
|
1018
|
-
|
|
1040
|
+
for (let qp of qpMeta.qps) {
|
|
1019
1041
|
if (DEBUG) {
|
|
1020
1042
|
urlKey = qp.urlKey;
|
|
1021
1043
|
qpOther = qpsByUrlKey[urlKey];
|
|
@@ -1061,19 +1083,15 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1061
1083
|
let routeInfos = state.routeInfos;
|
|
1062
1084
|
let qpMeta;
|
|
1063
1085
|
|
|
1064
|
-
for (let
|
|
1065
|
-
qpMeta = this._getQPMeta(
|
|
1086
|
+
for (let routeInfo of routeInfos) {
|
|
1087
|
+
qpMeta = this._getQPMeta(routeInfo);
|
|
1066
1088
|
|
|
1067
1089
|
if (!qpMeta) {
|
|
1068
1090
|
continue;
|
|
1069
1091
|
}
|
|
1070
1092
|
|
|
1071
|
-
let qp
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
for (let j = 0, qpLen = qpMeta.qps.length; j < qpLen; ++j) {
|
|
1075
|
-
qp = qpMeta.qps[j];
|
|
1076
|
-
presentProp = qp.prop in queryParams && qp.prop || qp.scopedPropertyName in queryParams && qp.scopedPropertyName || qp.urlKey in queryParams && qp.urlKey;
|
|
1093
|
+
for (let qp of qpMeta.qps) {
|
|
1094
|
+
let presentProp = qp.prop in queryParams && qp.prop || qp.scopedPropertyName in queryParams && qp.scopedPropertyName || qp.urlKey in queryParams && qp.urlKey;
|
|
1077
1095
|
|
|
1078
1096
|
if (presentProp) {
|
|
1079
1097
|
if (presentProp !== qp.scopedPropertyName) {
|
|
@@ -1103,15 +1121,17 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1103
1121
|
let qp;
|
|
1104
1122
|
let presentProp;
|
|
1105
1123
|
|
|
1106
|
-
for (let
|
|
1107
|
-
qpMeta = this._getQPMeta(
|
|
1124
|
+
for (let routeInfo of routeInfos) {
|
|
1125
|
+
qpMeta = this._getQPMeta(routeInfo);
|
|
1108
1126
|
|
|
1109
1127
|
if (!qpMeta) {
|
|
1110
1128
|
continue;
|
|
1111
|
-
}
|
|
1129
|
+
} // Needs to stay for index loop to avoid throwIfClosureRequired
|
|
1130
|
+
|
|
1112
1131
|
|
|
1113
1132
|
for (let j = 0, qpLen = qpMeta.qps.length; j < qpLen; ++j) {
|
|
1114
1133
|
qp = qpMeta.qps[j];
|
|
1134
|
+
assert('expected qp', qp);
|
|
1115
1135
|
presentProp = qp.prop in queryParams && qp.prop || qp.scopedPropertyName in queryParams && qp.scopedPropertyName || qp.urlKey in queryParams && qp.urlKey;
|
|
1116
1136
|
assert(`You passed the \`${presentProp}\` query parameter during a transition into ${qp.route.routeName}, please update to ${qp.urlKey}`, function () {
|
|
1117
1137
|
if (qp.urlKey === presentProp || qp.scopedPropertyName === presentProp) {
|
|
@@ -1188,12 +1208,16 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1188
1208
|
mountPoint
|
|
1189
1209
|
}) {
|
|
1190
1210
|
let engineInstances = this._engineInstances;
|
|
1211
|
+
let namedInstances = engineInstances[name];
|
|
1212
|
+
|
|
1213
|
+
if (!namedInstances) {
|
|
1214
|
+
namedInstances = Object.create(null);
|
|
1215
|
+
engineInstances[name] = namedInstances;
|
|
1216
|
+
} // We just set these!
|
|
1191
1217
|
|
|
1192
|
-
if (!engineInstances[name]) {
|
|
1193
|
-
engineInstances[name] = Object.create(null);
|
|
1194
|
-
}
|
|
1195
1218
|
|
|
1196
|
-
|
|
1219
|
+
assert('has namedInstances', namedInstances);
|
|
1220
|
+
let engineInstance = namedInstances[instanceId];
|
|
1197
1221
|
|
|
1198
1222
|
if (!engineInstance) {
|
|
1199
1223
|
let owner = getOwner(this);
|
|
@@ -1204,7 +1228,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1204
1228
|
mountPoint
|
|
1205
1229
|
});
|
|
1206
1230
|
engineInstance.boot();
|
|
1207
|
-
|
|
1231
|
+
namedInstances[instanceId] = engineInstance;
|
|
1208
1232
|
}
|
|
1209
1233
|
|
|
1210
1234
|
return engineInstance;
|
|
@@ -1231,6 +1255,7 @@ class EmberRouter extends EmberObject.extend(Evented) {
|
|
|
1231
1255
|
function forEachRouteAbove(routeInfos, callback) {
|
|
1232
1256
|
for (let i = routeInfos.length - 1; i >= 0; --i) {
|
|
1233
1257
|
let routeInfo = routeInfos[i];
|
|
1258
|
+
assert('has routeInfo', routeInfo);
|
|
1234
1259
|
let route = routeInfo.route; // routeInfo.handler being `undefined` generally means either:
|
|
1235
1260
|
//
|
|
1236
1261
|
// 1. an error occurred during creation of the route in question
|
|
@@ -1433,6 +1458,7 @@ export function triggerEvent(routeInfos, ignoreFailure, name, args) {
|
|
|
1433
1458
|
|
|
1434
1459
|
for (let i = routeInfos.length - 1; i >= 0; i--) {
|
|
1435
1460
|
routeInfo = routeInfos[i];
|
|
1461
|
+
assert('has routeInfo', routeInfo);
|
|
1436
1462
|
handler = routeInfo.route;
|
|
1437
1463
|
actionHandler = handler && handler.actions && handler.actions[name];
|
|
1438
1464
|
|
|
@@ -1470,9 +1496,8 @@ function calculatePostTransitionState(emberRouter, leafRouteName, contexts) {
|
|
|
1470
1496
|
params
|
|
1471
1497
|
} = state;
|
|
1472
1498
|
|
|
1473
|
-
for (let
|
|
1474
|
-
|
|
1475
|
-
|
|
1499
|
+
for (let routeInfo of routeInfos) {
|
|
1500
|
+
// If the routeInfo is not resolved, we serialize the context into params
|
|
1476
1501
|
if (!routeInfo.isResolved) {
|
|
1477
1502
|
params[routeInfo.name] = routeInfo.serialize(routeInfo.context);
|
|
1478
1503
|
} else {
|
|
@@ -1492,7 +1517,9 @@ function updatePaths(router) {
|
|
|
1492
1517
|
|
|
1493
1518
|
let path = EmberRouter._routePath(infos);
|
|
1494
1519
|
|
|
1495
|
-
let
|
|
1520
|
+
let info = infos[infos.length - 1];
|
|
1521
|
+
assert('expected info', info);
|
|
1522
|
+
let currentRouteName = info.name;
|
|
1496
1523
|
let location = router.location;
|
|
1497
1524
|
assert('expected location to not be a string', typeof location !== 'string');
|
|
1498
1525
|
let currentURL = location.getURL();
|
|
@@ -5,22 +5,28 @@ import EmberError from '@ember/error';
|
|
|
5
5
|
import { STATE_SYMBOL } from 'router_js';
|
|
6
6
|
const ALL_PERIODS_REGEX = /\./g;
|
|
7
7
|
export function extractRouteArgs(args) {
|
|
8
|
+
// SAFETY: This should just be the same thing
|
|
8
9
|
args = args.slice();
|
|
9
|
-
let
|
|
10
|
+
let possibleOptions = args[args.length - 1];
|
|
10
11
|
let queryParams;
|
|
11
12
|
|
|
12
|
-
if (
|
|
13
|
-
|
|
13
|
+
if (isRouteOptions(possibleOptions)) {
|
|
14
|
+
args.pop(); // Remove options
|
|
15
|
+
|
|
16
|
+
queryParams = possibleOptions.queryParams;
|
|
14
17
|
} else {
|
|
15
|
-
// Not query params so return to the array
|
|
16
|
-
args.push(possibleQueryParams);
|
|
17
18
|
queryParams = {};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let routeName;
|
|
22
|
+
|
|
23
|
+
if (typeof args[0] === 'string') {
|
|
24
|
+
routeName = args.shift(); // We just checked this!
|
|
25
|
+
|
|
26
|
+
assert('routeName is a string', typeof routeName === 'string');
|
|
27
|
+
} // SAFTEY: We removed the name and options if they existed, only models left.
|
|
21
28
|
|
|
22
29
|
|
|
23
|
-
let routeName = args.shift();
|
|
24
30
|
let models = args;
|
|
25
31
|
return {
|
|
26
32
|
routeName,
|
|
@@ -30,7 +36,9 @@ export function extractRouteArgs(args) {
|
|
|
30
36
|
}
|
|
31
37
|
export function getActiveTargetName(router) {
|
|
32
38
|
let routeInfos = router.activeTransition ? router.activeTransition[STATE_SYMBOL].routeInfos : router.state.routeInfos;
|
|
33
|
-
|
|
39
|
+
let lastRouteInfo = routeInfos[routeInfos.length - 1];
|
|
40
|
+
assert('has last route info', lastRouteInfo);
|
|
41
|
+
return lastRouteInfo.name;
|
|
34
42
|
}
|
|
35
43
|
export function stashParamNames(router, routeInfos) {
|
|
36
44
|
if (routeInfos['_namesStashed']) {
|
|
@@ -41,7 +49,9 @@ export function stashParamNames(router, routeInfos) {
|
|
|
41
49
|
// Hopefully we can remove this in the future.
|
|
42
50
|
|
|
43
51
|
|
|
44
|
-
let
|
|
52
|
+
let routeInfo = routeInfos[routeInfos.length - 1];
|
|
53
|
+
assert('has route info', routeInfo);
|
|
54
|
+
let targetRouteName = routeInfo.name;
|
|
45
55
|
|
|
46
56
|
let recogHandlers = router._routerMicrolib.recognizer.handlersFor(targetRouteName);
|
|
47
57
|
|
|
@@ -49,6 +59,7 @@ export function stashParamNames(router, routeInfos) {
|
|
|
49
59
|
|
|
50
60
|
for (let i = 0; i < routeInfos.length; ++i) {
|
|
51
61
|
let routeInfo = routeInfos[i];
|
|
62
|
+
assert('has route info', routeInfo);
|
|
52
63
|
let names = recogHandlers[i].names;
|
|
53
64
|
|
|
54
65
|
if (names.length) {
|
|
@@ -56,7 +67,7 @@ export function stashParamNames(router, routeInfos) {
|
|
|
56
67
|
}
|
|
57
68
|
|
|
58
69
|
routeInfo['_names'] = names;
|
|
59
|
-
let route = routeInfo.route;
|
|
70
|
+
let route = routeInfo.route; // SAFETY: This cast should be idential. I don't understand why it is needed.
|
|
60
71
|
|
|
61
72
|
route._stashNames(routeInfo, dynamicParent);
|
|
62
73
|
}
|
|
@@ -94,9 +105,7 @@ function _calculateCacheValuePrefix(prefix, part) {
|
|
|
94
105
|
export function calculateCacheKey(prefix, parts = [], values) {
|
|
95
106
|
let suffixes = '';
|
|
96
107
|
|
|
97
|
-
for (let
|
|
98
|
-
let part = parts[i];
|
|
99
|
-
|
|
108
|
+
for (let part of parts) {
|
|
100
109
|
let cacheValuePrefix = _calculateCacheValuePrefix(prefix, part);
|
|
101
110
|
|
|
102
111
|
let value;
|
|
@@ -151,8 +160,8 @@ export function calculateCacheKey(prefix, parts = [], values) {
|
|
|
151
160
|
export function normalizeControllerQueryParams(queryParams) {
|
|
152
161
|
let qpMap = {};
|
|
153
162
|
|
|
154
|
-
for (let
|
|
155
|
-
accumulateQueryParamDescriptors(
|
|
163
|
+
for (let queryParam of queryParams) {
|
|
164
|
+
accumulateQueryParamDescriptors(queryParam, qpMap);
|
|
156
165
|
}
|
|
157
166
|
|
|
158
167
|
return qpMap;
|
|
@@ -208,12 +217,14 @@ export function resemblesURL(str) {
|
|
|
208
217
|
*/
|
|
209
218
|
|
|
210
219
|
export function prefixRouteNameArg(route, args) {
|
|
211
|
-
let routeName
|
|
220
|
+
let routeName;
|
|
212
221
|
let owner = getOwner(route);
|
|
213
222
|
assert('Route is unexpectedly missing an owner', owner);
|
|
214
223
|
let prefix = owner.mountPoint; // only alter the routeName if it's actually referencing a route.
|
|
215
224
|
|
|
216
|
-
if (owner.routable && typeof
|
|
225
|
+
if (owner.routable && typeof args[0] === 'string') {
|
|
226
|
+
routeName = args[0];
|
|
227
|
+
|
|
217
228
|
if (resemblesURL(routeName)) {
|
|
218
229
|
throw new EmberError('Programmatic transitions by URL cannot be used within an Engine. Please use the route name instead.');
|
|
219
230
|
} else {
|
|
@@ -260,7 +271,7 @@ export function deprecateTransitionMethods(frameworkClass, methodName) {
|
|
|
260
271
|
});
|
|
261
272
|
}
|
|
262
273
|
|
|
263
|
-
function
|
|
274
|
+
function isRouteOptions(value) {
|
|
264
275
|
if (value && typeof value === 'object') {
|
|
265
276
|
let qps = value.queryParams;
|
|
266
277
|
|
|
@@ -21,16 +21,16 @@ const ActionHandler = Mixin.create({
|
|
|
21
21
|
/**
|
|
22
22
|
The collection of functions, keyed by name, available on this
|
|
23
23
|
`ActionHandler` as action targets.
|
|
24
|
-
|
|
24
|
+
These functions will be invoked when a matching `{{action}}` is triggered
|
|
25
25
|
from within a template and the application's current route is this route.
|
|
26
|
-
|
|
26
|
+
Actions can also be invoked from other parts of your application
|
|
27
27
|
via `ActionHandler#send`.
|
|
28
|
-
|
|
28
|
+
The `actions` hash will inherit action handlers from
|
|
29
29
|
the `actions` hash defined on extended parent classes
|
|
30
30
|
or mixins rather than just replace the entire hash, e.g.:
|
|
31
|
-
|
|
31
|
+
```app/mixins/can-display-banner.js
|
|
32
32
|
import Mixin from '@ember/mixin';
|
|
33
|
-
|
|
33
|
+
export default Mixin.create({
|
|
34
34
|
actions: {
|
|
35
35
|
displayBanner(msg) {
|
|
36
36
|
// ...
|
|
@@ -38,28 +38,28 @@ const ActionHandler = Mixin.create({
|
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
```
|
|
41
|
-
|
|
41
|
+
```app/routes/welcome.js
|
|
42
42
|
import Route from '@ember/routing/route';
|
|
43
43
|
import CanDisplayBanner from '../mixins/can-display-banner';
|
|
44
|
-
|
|
44
|
+
export default Route.extend(CanDisplayBanner, {
|
|
45
45
|
actions: {
|
|
46
46
|
playMusic() {
|
|
47
47
|
// ...
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
});
|
|
51
|
-
|
|
51
|
+
// `WelcomeRoute`, when active, will be able to respond
|
|
52
52
|
// to both actions, since the actions hash is merged rather
|
|
53
53
|
// then replaced when extending mixins / parent classes.
|
|
54
54
|
this.send('displayBanner');
|
|
55
55
|
this.send('playMusic');
|
|
56
56
|
```
|
|
57
|
-
|
|
57
|
+
Within a Controller, Route or Component's action handler,
|
|
58
58
|
the value of the `this` context is the Controller, Route or
|
|
59
59
|
Component object:
|
|
60
|
-
|
|
60
|
+
```app/routes/song.js
|
|
61
61
|
import Route from '@ember/routing/route';
|
|
62
|
-
|
|
62
|
+
export default Route.extend({
|
|
63
63
|
actions: {
|
|
64
64
|
myAction() {
|
|
65
65
|
this.controllerFor("song");
|
|
@@ -69,13 +69,13 @@ const ActionHandler = Mixin.create({
|
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
```
|
|
72
|
-
|
|
72
|
+
It is also possible to call `this._super(...arguments)` from within an
|
|
73
73
|
action handler if it overrides a handler defined on a parent
|
|
74
74
|
class or mixin:
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
Take for example the following routes:
|
|
76
|
+
```app/mixins/debug-route.js
|
|
77
77
|
import Mixin from '@ember/mixin';
|
|
78
|
-
|
|
78
|
+
export default Mixin.create({
|
|
79
79
|
actions: {
|
|
80
80
|
debugRouteInformation() {
|
|
81
81
|
console.debug("It's a-me, console.debug!");
|
|
@@ -83,54 +83,54 @@ const ActionHandler = Mixin.create({
|
|
|
83
83
|
}
|
|
84
84
|
});
|
|
85
85
|
```
|
|
86
|
-
|
|
86
|
+
```app/routes/annoying-debug.js
|
|
87
87
|
import Route from '@ember/routing/route';
|
|
88
88
|
import DebugRoute from '../mixins/debug-route';
|
|
89
|
-
|
|
89
|
+
export default Route.extend(DebugRoute, {
|
|
90
90
|
actions: {
|
|
91
91
|
debugRouteInformation() {
|
|
92
92
|
// also call the debugRouteInformation of mixed in DebugRoute
|
|
93
93
|
this._super(...arguments);
|
|
94
|
-
|
|
94
|
+
// show additional annoyance
|
|
95
95
|
window.alert(...);
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
});
|
|
99
99
|
```
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
## Bubbling
|
|
101
|
+
By default, an action will stop bubbling once a handler defined
|
|
102
102
|
on the `actions` hash handles it. To continue bubbling the action,
|
|
103
103
|
you must return `true` from the handler:
|
|
104
|
-
|
|
104
|
+
```app/router.js
|
|
105
105
|
Router.map(function() {
|
|
106
106
|
this.route("album", function() {
|
|
107
107
|
this.route("song");
|
|
108
108
|
});
|
|
109
109
|
});
|
|
110
110
|
```
|
|
111
|
-
|
|
111
|
+
```app/routes/album.js
|
|
112
112
|
import Route from '@ember/routing/route';
|
|
113
|
-
|
|
113
|
+
export default Route.extend({
|
|
114
114
|
actions: {
|
|
115
115
|
startPlaying: function() {
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
});
|
|
119
119
|
```
|
|
120
|
-
|
|
120
|
+
```app/routes/album-song.js
|
|
121
121
|
import Route from '@ember/routing/route';
|
|
122
|
-
|
|
122
|
+
export default Route.extend({
|
|
123
123
|
actions: {
|
|
124
124
|
startPlaying() {
|
|
125
125
|
// ...
|
|
126
|
-
|
|
126
|
+
if (actionShouldAlsoBeTriggeredOnParentRoute) {
|
|
127
127
|
return true;
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
});
|
|
132
132
|
```
|
|
133
|
-
|
|
133
|
+
@property actions
|
|
134
134
|
@type Object
|
|
135
135
|
@default null
|
|
136
136
|
@public
|
|
@@ -140,14 +140,14 @@ const ActionHandler = Mixin.create({
|
|
|
140
140
|
Triggers a named action on the `ActionHandler`. Any parameters
|
|
141
141
|
supplied after the `actionName` string will be passed as arguments
|
|
142
142
|
to the action target function.
|
|
143
|
-
|
|
143
|
+
If the `ActionHandler` has its `target` property set, actions may
|
|
144
144
|
bubble to the `target`. Bubbling happens when an `actionName` can
|
|
145
145
|
not be found in the `ActionHandler`'s `actions` hash or if the
|
|
146
146
|
action target function returns `true`.
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
Example
|
|
148
|
+
```app/routes/welcome.js
|
|
149
149
|
import Route from '@ember/routing/route';
|
|
150
|
-
|
|
150
|
+
export default Route.extend({
|
|
151
151
|
actions: {
|
|
152
152
|
playTheme() {
|
|
153
153
|
this.send('playMusic', 'theme.mp3');
|
|
@@ -158,7 +158,7 @@ const ActionHandler = Mixin.create({
|
|
|
158
158
|
}
|
|
159
159
|
});
|
|
160
160
|
```
|
|
161
|
-
|
|
161
|
+
@method send
|
|
162
162
|
@param {String} actionName The action to trigger
|
|
163
163
|
@param {*} context a context to send with the action
|
|
164
164
|
@public
|
|
@@ -11,8 +11,8 @@ import { ENV } from '@ember/-internals/environment';
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
export const DEFAULT_FEATURES = {
|
|
14
|
-
EMBER_LIBRARIES_ISREGISTERED:
|
|
15
|
-
EMBER_IMPROVED_INSTRUMENTATION:
|
|
14
|
+
EMBER_LIBRARIES_ISREGISTERED: false,
|
|
15
|
+
EMBER_IMPROVED_INSTRUMENTATION: false,
|
|
16
16
|
EMBER_NAMED_BLOCKS: true,
|
|
17
17
|
EMBER_GLIMMER_HELPER_MANAGER: true,
|
|
18
18
|
EMBER_GLIMMER_INVOKE_HELPER: true,
|
|
@@ -1,61 +1,10 @@
|
|
|
1
1
|
import { FrameworkObject } from '@ember/-internals/runtime';
|
|
2
2
|
import { inject as metalInject } from '@ember/-internals/metal';
|
|
3
3
|
import ControllerMixin from './lib/controller_mixin';
|
|
4
|
-
/**
|
|
5
|
-
@module @ember/controller
|
|
6
|
-
*/
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
@class Controller
|
|
10
|
-
@extends EmberObject
|
|
11
|
-
@uses Ember.ControllerMixin
|
|
12
|
-
@public
|
|
13
|
-
*/
|
|
5
|
+
class Controller extends FrameworkObject.extend(ControllerMixin) {}
|
|
14
6
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Creates a property that lazily looks up another controller in the container.
|
|
18
|
-
Can only be used when defining another controller.
|
|
19
|
-
|
|
20
|
-
Example:
|
|
21
|
-
|
|
22
|
-
```app/controllers/post.js
|
|
23
|
-
import Controller, {
|
|
24
|
-
inject as controller
|
|
25
|
-
} from '@ember/controller';
|
|
26
|
-
|
|
27
|
-
export default class PostController extends Controller {
|
|
28
|
-
@controller posts;
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Classic Class Example:
|
|
33
|
-
|
|
34
|
-
```app/controllers/post.js
|
|
35
|
-
import Controller, {
|
|
36
|
-
inject as controller
|
|
37
|
-
} from '@ember/controller';
|
|
38
|
-
|
|
39
|
-
export default Controller.extend({
|
|
40
|
-
posts: controller()
|
|
41
|
-
});
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
This example will create a `posts` property on the `post` controller that
|
|
45
|
-
looks up the `posts` controller in the container, making it easy to reference
|
|
46
|
-
other controllers.
|
|
47
|
-
|
|
48
|
-
@method inject
|
|
49
|
-
@static
|
|
50
|
-
@for @ember/controller
|
|
51
|
-
@since 1.10.0
|
|
52
|
-
@param {String} name (optional) name of the controller to inject, defaults to
|
|
53
|
-
the property's name
|
|
54
|
-
@return {ComputedDecorator} injection decorator instance
|
|
55
|
-
@public
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
|
-
export function inject() {
|
|
59
|
-
return metalInject('controller', ...arguments);
|
|
7
|
+
export function inject(...args) {
|
|
8
|
+
return metalInject('controller', ...args);
|
|
60
9
|
}
|
|
61
10
|
export default Controller;
|