1 | import { ParamDeclaration, RawParams } from '../params/interface';
|
2 | import { StateObject } from './stateObject';
|
3 | import { ViewContext } from '../view/interface';
|
4 | import { IInjectable } from '../common/common';
|
5 | import { Transition } from '../transition/transition';
|
6 | import { TransitionStateHookFn, TransitionOptions } from '../transition/interface';
|
7 | import { ResolvePolicy, ResolvableLiteral, ProviderLike } from '../resolve/interface';
|
8 | import { Resolvable } from '../resolve/resolvable';
|
9 | import { TargetState } from './targetState';
|
10 | export type StateOrName = string | StateDeclaration | StateObject;
|
11 | export interface TransitionPromise extends Promise<StateObject> {
|
12 | transition: Transition;
|
13 | }
|
14 | export interface TargetStateDef {
|
15 | state: StateOrName;
|
16 | params?: RawParams;
|
17 | options?: TransitionOptions;
|
18 | }
|
19 | export type ResolveTypes = Resolvable | ResolvableLiteral | ProviderLike;
|
20 | /**
|
21 | * Base interface for declaring a view
|
22 | *
|
23 | * This interface defines the basic data that a normalized view declaration will have on it.
|
24 | * Each implementation of UI-Router (for a specific framework) should define its own extension of this interface.
|
25 | * Add any additional fields that the framework requires to that interface.
|
26 | */
|
27 | export interface _ViewDeclaration {
|
28 | /**
|
29 | * The raw name for the view declaration, i.e., the [[StateDeclaration.views]] property name.
|
30 | */
|
31 | $name?: string;
|
32 | /**
|
33 | * The normalized address for the `ui-view` which this ViewConfig targets.
|
34 | *
|
35 | * A ViewConfig targets a `ui-view` in the DOM (relative to the `uiViewContextAnchor`) which has
|
36 | * a specific name.
|
37 | * @example `header` or `$default`
|
38 | *
|
39 | * The `uiViewName` can also target a _nested view_ by providing a dot-notation address
|
40 | * @example `foo.bar` or `foo.$default.bar`
|
41 | */
|
42 | $uiViewName?: string;
|
43 | /**
|
44 | * The normalized context anchor (state name) for the `uiViewName`
|
45 | *
|
46 | * When targeting a `ui-view`, the `uiViewName` address is anchored to a context name (state name).
|
47 | */
|
48 | $uiViewContextAnchor?: string;
|
49 | /**
|
50 | * A type identifier for the View
|
51 | *
|
52 | * This is used when loading prerequisites for the view, before it enters the DOM. Different types of views
|
53 | * may load differently (e.g., templateProvider+controllerProvider vs component class)
|
54 | */
|
55 | $type?: string;
|
56 | /**
|
57 | * The context that this view is declared within.
|
58 | */
|
59 | $context?: ViewContext;
|
60 | }
|
61 | /**
|
62 | * The return value of a [[redirectTo]] function
|
63 | *
|
64 | * - string: a state name
|
65 | * - TargetState: a target state, parameters, and options
|
66 | * - object: an object with a state name and parameters
|
67 | */
|
68 | export type RedirectToResult = string | TargetState | {
|
69 | state?: string;
|
70 | params?: RawParams;
|
71 | } | void;
|
72 | /**
|
73 | * The StateDeclaration object is used to define a state or nested state.
|
74 | *
|
75 | * Note: Each implementation of UI-Router (for a specific framework)
|
76 | * extends this interface as necessary.
|
77 | *
|
78 | * #### Example:
|
79 | * ```js
|
80 | * // StateDeclaration object
|
81 | * var foldersState = {
|
82 | * name: 'folders',
|
83 | * url: '/folders',
|
84 | * component: FoldersComponent,
|
85 | * resolve: {
|
86 | * allfolders: function(FolderService) {
|
87 | * return FolderService.list();
|
88 | * }
|
89 | * },
|
90 | * }
|
91 | *
|
92 | * registry.register(foldersState);
|
93 | * ```
|
94 | */
|
95 | export interface StateDeclaration {
|
96 | /**
|
97 | * The state name (required)
|
98 | *
|
99 | * A unique state name, e.g. `"home"`, `"about"`, `"contacts"`.
|
100 | * To create a parent/child state use a dot, e.g. `"about.sales"`, `"home.newest"`.
|
101 | *
|
102 | * Note: [State] objects require unique names.
|
103 | * The name is used like an id.
|
104 | */
|
105 | name?: string;
|
106 | /**
|
107 | * Abstract state indicator
|
108 | *
|
109 | * An abstract state can never be directly activated.
|
110 | * Use an abstract state to provide inherited properties (url, resolve, data, etc) to children states.
|
111 | */
|
112 | abstract?: boolean;
|
113 | /**
|
114 | * The parent state
|
115 | *
|
116 | * Normally, a state's parent is implied from the state's [[name]], e.g., `"parentstate.childstate"`.
|
117 | *
|
118 | * Alternatively, you can explicitly set the parent state using this property.
|
119 | * This allows shorter state names, e.g., `<a ui-sref="childstate">Child</a>`
|
120 | * instead of `<a ui-sref="parentstate.childstate">Child</a>
|
121 | *
|
122 | * When using this property, the state's name should not have any dots in it.
|
123 | *
|
124 | * #### Example:
|
125 | * ```js
|
126 | * var parentstate = {
|
127 | * name: 'parentstate'
|
128 | * }
|
129 | * var childstate = {
|
130 | * name: 'childstate',
|
131 | * parent: 'parentstate'
|
132 | * // or use a JS var which is the parent StateDeclaration, i.e.:
|
133 | * // parent: parentstate
|
134 | * }
|
135 | * ```
|
136 | */
|
137 | parent?: string | StateDeclaration;
|
138 | /**
|
139 | * Gets the internal State object API
|
140 | *
|
141 | * Gets the *internal API* for a registered state.
|
142 | *
|
143 | * Note: the internal [[StateObject]] API is subject to change without notice
|
144 | * @internal
|
145 | */
|
146 | $$state?: () => StateObject;
|
147 | /**
|
148 | * Resolve - a mechanism to asynchronously fetch data, participating in the Transition lifecycle
|
149 | *
|
150 | * The `resolve:` property defines data (or other dependencies) to be fetched asynchronously when the state is being entered.
|
151 | * After the data is fetched, it may be used in views, transition hooks or other resolves that belong to this state.
|
152 | * The data may also be used in any views or resolves that belong to nested states.
|
153 | *
|
154 | * ### As an array
|
155 | *
|
156 | * Each array element should be a [[ResolvableLiteral]] object.
|
157 | *
|
158 | * #### Example:
|
159 | * The `user` resolve injects the current `Transition` and the `UserService` (using its token, which is a string).
|
160 | * The [[ResolvableLiteral.resolvePolicy]] sets how the resolve is processed.
|
161 | * The `user` data, fetched asynchronously, can then be used in a view.
|
162 | * ```js
|
163 | * var state = {
|
164 | * name: 'user',
|
165 | * url: '/user/:userId
|
166 | * resolve: [
|
167 | * {
|
168 | * token: 'user',
|
169 | * policy: { when: 'EAGER' },
|
170 | * deps: ['UserService', Transition],
|
171 | * resolveFn: (userSvc, trans) => userSvc.fetchUser(trans.params().userId) },
|
172 | * }
|
173 | * ]
|
174 | * }
|
175 | * ```
|
176 | *
|
177 | * Note: an Angular 2 style [`useFactory` provider literal](https://angular.io/docs/ts/latest/cookbook/dependency-injection.html#!#provide)
|
178 | * may also be used. See [[ProviderLike]].
|
179 | * #### Example:
|
180 | * ```
|
181 | * resolve: [
|
182 | * { provide: 'token', useFactory: (http) => http.get('/'), deps: [ Http ] },
|
183 | * ]
|
184 | * ```
|
185 | *
|
186 | * ### As an object
|
187 | *
|
188 | * The `resolve` property may be an object where:
|
189 | * - Each key (string) is the name of the dependency.
|
190 | * - Each value (function) is an injectable function which returns the dependency, or a promise for the dependency.
|
191 | *
|
192 | * This style is based on AngularJS injectable functions, but can be used with any UI-Router implementation.
|
193 | * If your code will be minified, the function should be ["annotated" in the AngularJS manner](https://docs.angularjs.org/guide/di#dependency-annotation).
|
194 | *
|
195 | * #### AngularJS Example:
|
196 | * ```js
|
197 | * resolve: {
|
198 | * // If you inject `myStateDependency` into a controller, you'll get "abc"
|
199 | * myStateDependency: function() {
|
200 | * return "abc";
|
201 | * },
|
202 | * // Dependencies are annotated in "Inline Array Annotation"
|
203 | * myAsyncData: ['$http', '$transition$' function($http, $transition$) {
|
204 | * // Return a promise (async) for the data
|
205 | * return $http.get("/foos/" + $transition$.params().foo);
|
206 | * }]
|
207 | * }
|
208 | * ```
|
209 | *
|
210 | * Note: You cannot specify a policy for each Resolvable, nor can you use non-string
|
211 | * tokens when using the object style `resolve:` block.
|
212 | *
|
213 | * ### Lifecycle
|
214 | *
|
215 | * Since a resolve function can return a promise, the router will delay entering the state until the promises are ready.
|
216 | * If any of the promises are rejected, the Transition is aborted with an Error.
|
217 | *
|
218 | * By default, resolves for a state are fetched just before that state is entered.
|
219 | * Note that only states which are being *entered* during the `Transition` have their resolves fetched.
|
220 | * States that are "retained" do not have their resolves re-fetched.
|
221 | *
|
222 | * If you are currently in a parent state `parent` and are transitioning to a child state `parent.child`, the
|
223 | * previously resolved data for state `parent` can be injected into `parent.child` without delay.
|
224 | *
|
225 | * Any resolved data for `parent.child` is retained until `parent.child` is exited, e.g., by transitioning back to the `parent` state.
|
226 | *
|
227 | * Because of this scoping and lifecycle, resolves are a great place to fetch your application's primary data.
|
228 | *
|
229 | * ### Injecting resolves into other things
|
230 | *
|
231 | * During a transition, Resolve data can be injected into:
|
232 | *
|
233 | * - Views (the components which fill a `ui-view` tag)
|
234 | * - Transition Hooks
|
235 | * - Other resolves (a resolve may depend on asynchronous data from a different resolve)
|
236 | *
|
237 | * ### Injecting other things into resolves
|
238 | *
|
239 | * Resolve functions usually have dependencies on some other API(s).
|
240 | * The dependencies are usually declared and injected into the resolve function.
|
241 | * A common pattern is to inject a custom service such as `UserService`.
|
242 | * The resolve then delegates to a service method, such as `UserService.list()`;
|
243 | *
|
244 | * #### Special injectable tokens
|
245 | *
|
246 | * - `UIRouter`: The [[UIRouter]] instance which has references to all the UI-Router services.
|
247 | * - `Transition`: The current [[Transition]] object; information and API about the current transition, such as
|
248 | * "to" and "from" State Parameters and transition options.
|
249 | * - `'$transition$'`: A string alias for the `Transition` injectable
|
250 | * - `'$state$'`: For `onEnter`/`onExit`/`onRetain`, the state being entered/exited/retained.
|
251 | * - Other resolve tokens: A resolve can depend on another resolve, either from the same state, or from any parent state.
|
252 | *
|
253 | * #### Example:
|
254 | * ```js
|
255 | * // Injecting a resolve into another resolve
|
256 | * resolve: [
|
257 | * // Define a resolve 'allusers' which delegates to the UserService.list()
|
258 | * // which returns a promise (async) for all the users
|
259 | * { provide: 'allusers', useFactory: (UserService) => UserService.list(), deps: [UserService] },
|
260 | *
|
261 | * // Define a resolve 'user' which depends on the allusers resolve.
|
262 | * // This resolve function is not called until 'allusers' is ready.
|
263 | * { provide: 'user', (allusers, trans) => _.find(allusers, trans.params().userId, deps: ['allusers', Transition] }
|
264 | * }
|
265 | * ```
|
266 | */
|
267 | resolve?: ResolveTypes[] | {
|
268 | [key: string]: IInjectable;
|
269 | };
|
270 | /**
|
271 | * Sets the resolve policy defaults for all resolves on this state
|
272 | *
|
273 | * This should be an [[ResolvePolicy]] object.
|
274 | *
|
275 | * It can contain the following optional keys/values:
|
276 | *
|
277 | * - `when`: (optional) defines when the resolve is fetched. Accepted values: "LAZY" or "EAGER"
|
278 | * - `async`: (optional) if the transition waits for the resolve. Accepted values: "WAIT", "NOWAIT", {@link CustomAsyncPolicy}
|
279 | *
|
280 | * See [[ResolvePolicy]] for more details.
|
281 | */
|
282 | resolvePolicy?: ResolvePolicy;
|
283 | /**
|
284 | * The url fragment for the state
|
285 | *
|
286 | * A URL fragment (with optional parameters) which is used to match the browser location with this state.
|
287 | *
|
288 | * This fragment will be appended to the parent state's URL in order to build up the overall URL for this state.
|
289 | * See [[UrlMatcher]] for details on acceptable patterns.
|
290 | *
|
291 | * @examples
|
292 | * ```js
|
293 | *
|
294 | * url: "/home"
|
295 | * // Define a parameter named 'userid'
|
296 | * url: "/users/:userid"
|
297 | * // param 'bookid' has a custom regexp
|
298 | * url: "/books/{bookid:[a-zA-Z_-]}"
|
299 | * // param 'categoryid' is of type 'int'
|
300 | * url: "/books/{categoryid:int}"
|
301 | * // two parameters for this state
|
302 | * url: "/books/{publishername:string}/{categoryid:int}"
|
303 | * // Query parameters
|
304 | * url: "/messages?before&after"
|
305 | * // Query parameters of type 'date'
|
306 | * url: "/messages?{before:date}&{after:date}"
|
307 | * // Path and query parameters
|
308 | * url: "/messages/:mailboxid?{before:date}&{after:date}"
|
309 | * ```
|
310 | */
|
311 | url?: string;
|
312 | /**
|
313 | * Params configuration
|
314 | *
|
315 | * An object which optionally configures parameters declared in the url, or defines additional non-url
|
316 | * parameters. For each parameter being configured, add a [[ParamDeclaration]] keyed to the name of the parameter.
|
317 | *
|
318 | * #### Example:
|
319 | * ```js
|
320 | * params: {
|
321 | * param1: {
|
322 | * type: "int",
|
323 | * array: true,
|
324 | * value: []
|
325 | * },
|
326 | * param2: {
|
327 | * value: "index"
|
328 | * }
|
329 | * }
|
330 | * ```
|
331 | */
|
332 | params?: {
|
333 | [key: string]: ParamDeclaration | any;
|
334 | };
|
335 | /**
|
336 | * Named views
|
337 | *
|
338 | * An optional object which defines multiple views, or explicitly targets specific named ui-views.
|
339 | *
|
340 | * - What is a view config
|
341 | * - What is a ui-view
|
342 | * - Shorthand controller/template
|
343 | * - Incompatible with ^
|
344 | *
|
345 | * Examples:
|
346 | *
|
347 | * Targets three named ui-views in the parent state's template
|
348 | *
|
349 | * #### Example:
|
350 | * ```js
|
351 | * views: {
|
352 | * header: {
|
353 | * controller: "headerCtrl",
|
354 | * templateUrl: "header.html"
|
355 | * }, body: {
|
356 | * controller: "bodyCtrl",
|
357 | * templateUrl: "body.html"
|
358 | * }, footer: {
|
359 | * controller: "footCtrl",
|
360 | * templateUrl: "footer.html"
|
361 | * }
|
362 | * }
|
363 | * ```
|
364 | *
|
365 | * @example
|
366 | * ```js
|
367 | * // Targets named ui-view="header" from ancestor state 'top''s template, and
|
368 | * // named `ui-view="body" from parent state's template.
|
369 | * views: {
|
370 | * 'header@top': {
|
371 | * controller: "msgHeaderCtrl",
|
372 | * templateUrl: "msgHeader.html"
|
373 | * }, 'body': {
|
374 | * controller: "messagesCtrl",
|
375 | * templateUrl: "messages.html"
|
376 | * }
|
377 | * }
|
378 | * ```
|
379 | */
|
380 | views?: {
|
381 | [key: string]: _ViewDeclaration;
|
382 | };
|
383 | /**
|
384 | * An inherited property to store state data
|
385 | *
|
386 | * This is a spot for you to store inherited state metadata.
|
387 | * Child states' `data` object will prototypally inherit from their parent state.
|
388 | *
|
389 | * This is a good spot to put metadata such as `requiresAuth`.
|
390 | *
|
391 | * Note: because prototypal inheritance is used, changes to parent `data` objects reflect in the child `data` objects.
|
392 | * Care should be taken if you are using `hasOwnProperty` on the `data` object.
|
393 | * Properties from parent objects will return false for `hasOwnProperty`.
|
394 | */
|
395 | data?: any;
|
396 | /**
|
397 | * Synchronously or asynchronously redirects Transitions to a different state/params
|
398 | *
|
399 | * If this property is defined, a Transition directly to this state will be redirected based on the property's value.
|
400 | *
|
401 | * - If the value is a `string`, the Transition is redirected to the state named by the string.
|
402 | *
|
403 | * - If the property is an object with a `state` and/or `params` property,
|
404 | * the Transition is redirected to the named `state` and/or `params`.
|
405 | *
|
406 | * - If the value is a [[TargetState]] the Transition is redirected to the `TargetState`
|
407 | *
|
408 | * - If the property is a function:
|
409 | * - The function is called with the current [[Transition]]
|
410 | * - The return value is processed using the previously mentioned rules.
|
411 | * - If the return value is a promise, the promise is waited for, then the resolved async value is processed using the same rules.
|
412 | *
|
413 | * Note: `redirectTo` is processed as an `onStart` hook, before `LAZY` resolves.
|
414 | * If your redirect function relies on resolve data, get the [[Transition.injector]] and get a
|
415 | * promise for the resolve data using [[UIInjector.getAsync]].
|
416 | *
|
417 | * #### Example:
|
418 | * ```js
|
419 | * // a string
|
420 | * .state('A', {
|
421 | * redirectTo: 'A.B'
|
422 | * })
|
423 | *
|
424 | * // a {state, params} object
|
425 | * .state('C', {
|
426 | * redirectTo: { state: 'C.D', params: { foo: 'index' } }
|
427 | * })
|
428 | *
|
429 | * // a fn
|
430 | * .state('E', {
|
431 | * redirectTo: () => "A"
|
432 | * })
|
433 | *
|
434 | * // a fn conditionally returning a {state, params}
|
435 | * .state('F', {
|
436 | * redirectTo: (trans) => {
|
437 | * if (trans.params().foo < 10)
|
438 | * return { state: 'F', params: { foo: 10 } };
|
439 | * }
|
440 | * })
|
441 | *
|
442 | * // a fn returning a promise for a redirect
|
443 | * .state('G', {
|
444 | * redirectTo: (trans) => {
|
445 | * let svc = trans.injector().get('SomeAsyncService')
|
446 | * let promise = svc.getAsyncRedirectTo(trans.params.foo);
|
447 | * return promise;
|
448 | * }
|
449 | * })
|
450 | *
|
451 | * // a fn that fetches resolve data
|
452 | * .state('G', {
|
453 | * redirectTo: (trans) => {
|
454 | * // getAsync tells the resolve to load
|
455 | * let resolvePromise = trans.injector().getAsync('SomeResolve')
|
456 | * return resolvePromise.then(resolveData => resolveData === 'login' ? 'login' : null);
|
457 | * }
|
458 | * })
|
459 | * ```
|
460 | */
|
461 | redirectTo?: RedirectToResult | ((transition: Transition) => RedirectToResult) | ((transition: Transition) => Promise<RedirectToResult>);
|
462 | /**
|
463 | * A Transition Hook called with the state is being entered. See: [[IHookRegistry.onEnter]]
|
464 | *
|
465 | * #### Example:
|
466 | * ```js
|
467 | * .state({
|
468 | * name: 'mystate',
|
469 | * onEnter: function(trans, state) {
|
470 | * console.log("Entering " + state.name);
|
471 | * }
|
472 | * });
|
473 | * ```
|
474 | *
|
475 | * Note: The above `onEnter` on the state declaration is effectively sugar for:
|
476 | *
|
477 | * ```js
|
478 | * transitionService.onEnter({ entering: 'mystate' }, function(trans, state) {
|
479 | * console.log("Entering " + state.name);
|
480 | * });
|
481 | * ```
|
482 | */
|
483 | onEnter?: TransitionStateHookFn;
|
484 | /**
|
485 | * A [[TransitionStateHookFn]] called with the state is being retained/kept. See: [[IHookRegistry.onRetain]]
|
486 | *
|
487 | * #### Example:
|
488 | * ```js
|
489 | * .state({
|
490 | * name: 'mystate',
|
491 | * onRetain: function(trans, state) {
|
492 | * console.log(state.name + " is still active!");
|
493 | * }
|
494 | * });
|
495 | * ```
|
496 | *
|
497 | * Note: The above `onRetain` on the state declaration is effectively sugar for:
|
498 | *
|
499 | * ```js
|
500 | * transitionService.onRetain({ retained: 'mystate' }, function(trans, state) {
|
501 | * console.log(state.name + " is still active!");
|
502 | * });
|
503 | * ```
|
504 | */
|
505 | onRetain?: TransitionStateHookFn;
|
506 | /**
|
507 | * A Transition Hook called with the state is being exited. See: [[IHookRegistry.onExit]]
|
508 | *
|
509 | * #### Example:
|
510 | * ```js
|
511 | * .state({
|
512 | * name: 'mystate',
|
513 | * onExit: function(trans, state) {
|
514 | * console.log("Leaving " + state.name);
|
515 | * }
|
516 | * });
|
517 | * ```
|
518 | *
|
519 | * Note: The above `onRetain` on the state declaration is effectively sugar for:
|
520 | *
|
521 | * ```js
|
522 | * transitionService.onExit({ exiting: 'mystate' }, function(trans, state) {
|
523 | * console.log("Leaving " + state.name);
|
524 | * });
|
525 | * ```
|
526 | */
|
527 | onExit?: TransitionStateHookFn;
|
528 | /**
|
529 | * A function used to lazy load code
|
530 | *
|
531 | * The `lazyLoad` function is invoked before the state is activated.
|
532 | * The transition waits while the code is loading.
|
533 | *
|
534 | * The function should load the code that is required to activate the state.
|
535 | * For example, it may load a component class, or some service code.
|
536 | * The function must return a promise which resolves when loading is complete.
|
537 | *
|
538 | * For example, this code lazy loads a service before the `abc` state is activated:
|
539 | *
|
540 | * ```
|
541 | * .state('abc', {
|
542 | * lazyLoad: (transition, state) => import('./abcService')
|
543 | * }
|
544 | * ```
|
545 | *
|
546 | * The `abcService` file is imported and loaded
|
547 | * (it is assumed that the `abcService` file knows how to register itself as a service).
|
548 | *
|
549 | * #### Lifecycle
|
550 | *
|
551 | * - The `lazyLoad` function is invoked if a transition is going to enter the state.
|
552 | * - The function is invoked before the transition starts (using an `onBefore` transition hook).
|
553 | * - The function is only invoked once; while the `lazyLoad` function is loading code, it will not be invoked again.
|
554 | * For example, if the user double clicks a ui-sref, `lazyLoad` is only invoked once even though there were two transition attempts.
|
555 | * Instead, the existing lazy load promise is re-used.
|
556 | * - When the promise resolves successfully, the `lazyLoad` property is deleted from the state declaration.
|
557 | * - If the promise resolves to a [[LazyLoadResult]] which has an array of `states`, those states are registered.
|
558 | * - The original transition is retried (this time without the `lazyLoad` property present).
|
559 | *
|
560 | * - If the `lazyLoad` function fails, then the transition also fails.
|
561 | * The failed transition (and the `lazyLoad` function) could potentially be retried by the user.
|
562 | *
|
563 | * ### Lazy loading state definitions (Future States)
|
564 | *
|
565 | * State definitions can also be lazy loaded.
|
566 | * This might be desirable when building large, multi-module applications.
|
567 | *
|
568 | * To lazy load state definitions, a Future State should be registered as a placeholder.
|
569 | * When the state definitions are lazy loaded, the Future State is deregistered.
|
570 | *
|
571 | * A future state can act as a placeholder for a single state, or for an entire module of states and substates.
|
572 | * A future state should have:
|
573 | *
|
574 | * - A `name` which ends in `.**`.
|
575 | * A future state's `name` property acts as a wildcard [[Glob]].
|
576 | * It matches any state name that starts with the `name` (including child states that are not yet loaded).
|
577 | * - A `url` prefix.
|
578 | * A future state's `url` property acts as a wildcard.
|
579 | * UI-Router matches all paths that begin with the `url`.
|
580 | * It effectively appends `.*` to the internal regular expression.
|
581 | * When the prefix matches, the future state will begin loading.
|
582 | * - A `lazyLoad` function.
|
583 | * This function should should return a Promise to lazy load the code for one or more [[StateDeclaration]] objects.
|
584 | * It should return a [[LazyLoadResult]].
|
585 | * Generally, one of the lazy loaded states should have the same name as the future state.
|
586 | * The new state will then **replace the future state placeholder** in the registry.
|
587 | *
|
588 | * ### Additional resources
|
589 | *
|
590 | * For in depth information on lazy loading and Future States, see the [Lazy Loading Guide](https://ui-router.github.io/guides/lazyload).
|
591 | *
|
592 | * #### Example: states.js
|
593 | * ```js
|
594 | *
|
595 | * // This child state is a lazy loaded future state
|
596 | * // The `lazyLoad` function loads the final state definition
|
597 | * {
|
598 | * name: 'parent.**',
|
599 | * url: '/parent',
|
600 | * lazyLoad: () => import('./lazy.states.js')
|
601 | * }
|
602 | * ```
|
603 | *
|
604 | * #### Example: lazy.states.js
|
605 | *
|
606 | * This file is lazy loaded. It exports an array of states.
|
607 | *
|
608 | * ```js
|
609 | * import {ChildComponent} from "./child.component.js";
|
610 | * import {ParentComponent} from "./parent.component.js";
|
611 | *
|
612 | * // This fully defined state replaces the future state
|
613 | * let parentState = {
|
614 | * // the name should match the future state
|
615 | * name: 'parent',
|
616 | * url: '/parent/:parentId',
|
617 | * component: ParentComponent,
|
618 | * resolve: {
|
619 | * parentData: ($transition$, ParentService) =>
|
620 | * ParentService.get($transition$.params().parentId)
|
621 | * }
|
622 | * }
|
623 | *
|
624 | * let childState = {
|
625 | * name: 'parent.child',
|
626 | * url: '/child/:childId',
|
627 | * params: {
|
628 | * childId: "default"
|
629 | * },
|
630 | * resolve: {
|
631 | * childData: ($transition$, ChildService) =>
|
632 | * ChildService.get($transition$.params().childId)
|
633 | * }
|
634 | * };
|
635 | *
|
636 | * // This array of states will be registered by the lazyLoad hook
|
637 | * let lazyLoadResults = {
|
638 | * states: [ parentState, childState ]
|
639 | * };
|
640 | *
|
641 | * export default lazyLoadResults;
|
642 | * ```
|
643 | *
|
644 | * @param transition the [[Transition]] that is activating the future state
|
645 | * @param state the [[StateDeclaration]] that the `lazyLoad` function is declared on
|
646 | * @return a Promise to load the states.
|
647 | * Optionally, if the promise resolves to a [[LazyLoadResult]],
|
648 | * the states will be registered with the [[StateRegistry]].
|
649 | */
|
650 | lazyLoad?: (transition: Transition, state: StateDeclaration) => Promise<LazyLoadResult>;
|
651 | /**
|
652 | * Marks all the state's parameters as `dynamic`.
|
653 | *
|
654 | * All parameters on the state will use this value for `dynamic` as a default.
|
655 | * Individual parameters may override this default using [[ParamDeclaration.dynamic]] in the [[params]] block.
|
656 | *
|
657 | * Note: this value overrides the `dynamic` value on a custom parameter type ([[ParamTypeDefinition.dynamic]]).
|
658 | */
|
659 | dynamic?: boolean;
|
660 | /**
|
661 | * Marks all query parameters as [[ParamDeclaration.dynamic]]
|
662 | *
|
663 | * @deprecated use either [[dynamic]] or [[ParamDeclaration.dynamic]]
|
664 | */
|
665 | reloadOnSearch?: boolean;
|
666 | }
|
667 | /**
|
668 | * The return type of a [[StateDeclaration.lazyLoad]] function
|
669 | *
|
670 | * If your state has a `lazyLoad` function, it should return a promise.
|
671 | * If promise resolves to an object matching this interface, then the `states` array
|
672 | * of [[StateDeclaration]] objects will be automatically registered.
|
673 | */
|
674 | export interface LazyLoadResult {
|
675 | states?: StateDeclaration[];
|
676 | }
|
677 | /**
|
678 | * An options object for [[StateService.href]]
|
679 | */
|
680 | export interface HrefOptions {
|
681 | /**
|
682 | * Defines what state to be "relative from"
|
683 | *
|
684 | * When a relative path is found (e.g `^` or `.bar`), defines which state to be relative from.
|
685 | */
|
686 | relative?: StateOrName;
|
687 | /**
|
688 | * If true, and if there is no url associated with the state provided in the
|
689 | * first parameter, then the constructed href url will be built from the first
|
690 | * ancestor which has a url.
|
691 | */
|
692 | lossy?: boolean;
|
693 | /**
|
694 | * If `true` will inherit parameters from the current parameter values.
|
695 | */
|
696 | inherit?: boolean;
|
697 | /**
|
698 | * If true will generate an absolute url, e.g. `http://www.example.com/fullurl`.
|
699 | */
|
700 | absolute?: boolean;
|
701 | }
|
702 | /**
|
703 | * Either a [[StateDeclaration]] or an ES6 class that implements [[StateDeclaration]]
|
704 | * The ES6 class constructor should have no arguments.
|
705 | */
|
706 | export type _StateDeclaration = StateDeclaration | {
|
707 | new (): StateDeclaration;
|
708 | };
|
709 |
|
\ | No newline at end of file |