@@ -504,66 +504,106 @@ export interface StateDeclaration {
504
504
onExit ?: TransitionStateHookFn ;
505
505
506
506
/**
507
- * A function which lazy loads the state definition (and child state definitions)
507
+ * A function used to lazy load code
508
508
*
509
- * A state which has a `lazyLoad` function is treated as a **temporary
510
- * placeholder** for a state definition that will be lazy loaded some time
511
- * in the future.
512
- * These temporary placeholder states are called "**Future States**".
509
+ * The `lazyLoad` function is invoked before the state is activated.
510
+ * The transition waits while the code is loading.
513
511
*
512
+ * The function should load the code that is required to activate the state.
513
+ * For example, it may load a component class, or some service code.
514
+ * The function must retur a promise which resolves when loading is complete.
514
515
*
515
- * #### `lazyLoad` :
516
+ * For example, this code lazy loads a service before the `abc` state is activated :
516
517
*
517
- * A future state's `lazyLoad` function should return a Promise to lazy load the
518
- * code for one or more lazy loaded [[StateDeclaration]] objects.
518
+ * ```
519
+ * .state('abc', {
520
+ * lazyLoad: (transition, state) => System.import('./abcService')
521
+ * }
522
+ * ```
519
523
*
520
- * If the promise resolves to an object with a `states: []` array,
521
- * the lazy loaded states will be registered with the [[StateRegistry]].
522
- * Generally, of the lazy loaded states should have the same name as the future state;
523
- * then it will **replace the future state placeholder** in the registry.
524
+ * The `abcService` file is imported and loaded
525
+ * (it is assumed that the `abcService` file knows how to register itself as a service).
524
526
*
525
- * In any case, when the promise successfully resolves, the placeholder Future State will be deregistered.
527
+ * #### Lifecycle
526
528
*
527
- * #### `url`
529
+ * - The `lazyLoad` function is invoked if a transition is going to enter the state.
530
+ * - The function is invoked before the transition starts (using an `onBefore` transition hook).
531
+ * - The function is only invoked once; while the `lazyLoad` function is loading code, it will not be invoked again.
532
+ * For example, if the user double clicks a ui-sref, `lazyLoad` is only invoked once even though there were two transition attempts.
533
+ * Instead, the existing lazy load promise is re-used.
534
+ * - When the promise resolves successfully, the `lazyLoad` property is deleted from the state declaration.
535
+ * - If the promise resolves to a [[LazyLoadResult]] which has an array of `states`, those states are registered.
536
+ * - The original transition is retried (this time without the `lazyLoad` property present).
528
537
*
529
- * A future state's `url` property acts as a wildcard.
538
+ * - If the `lazyLoad` function fails, then the transition also fails.
539
+ * The failed transition (and the `lazyLoad` function) could potentially be retried by the user.
530
540
*
531
- * UI-Router matches all paths that begin with the `url`.
532
- * It effectively appends `.*` to the internal regular expression.
541
+ * ### Lazy loading state definitions (Future States)
533
542
*
534
- * #### `name`
543
+ * State definitions can also be lazy loaded.
544
+ * This might be desirable when building large, multi-module applications.
535
545
*
536
- * A future state's `name` property acts as a wildcard.
546
+ * To lazy load state definitions, a Future State should be registered as a placeholder.
547
+ * When the state definitions are lazy loaded, the Future State is deregistered.
537
548
*
538
- * It matches any state name that starts with the `name` .
539
- * UI-Router effectively matches the future state using a `.**` [[Glob]] appended to the `name`.
549
+ * A future state can act as a placeholder for a single state, or for an entire module of states and substates .
550
+ * A future state should have:
540
551
*
541
- * @example
542
- * #### states.js
552
+ * - A `name` which ends in `.**`.
553
+ * A future state's `name` property acts as a wildcard [[Glob]].
554
+ * It matches any state name that starts with the `name` (including child states that are not yet loaded).
555
+ * - A `url` prefix.
556
+ * A future state's `url` property acts as a wildcard.
557
+ * UI-Router matches all paths that begin with the `url`.
558
+ * It effectively appends `.*` to the internal regular expression.
559
+ * When the prefix matches, the future state will begin loading.
560
+ * - A `lazyLoad` function.
561
+ * This function should should return a Promise to lazy load the code for one or more [[StateDeclaration]] objects.
562
+ * It should return a [[LazyLoadResult]].
563
+ * Generally, one of the lazy loaded states should have the same name as the future state.
564
+ * The new state will then **replace the future state placeholder** in the registry.
565
+ *
566
+ * ### Additional resources
567
+ *
568
+ * For in depth information on lazy loading and Future States, see the [Lazy Loading Guide](https://ui-router.github.io/guides/lazyload).
569
+ *
570
+ * #### Example: states.js
543
571
* ```js
544
572
*
545
573
* // This child state is a lazy loaded future state
546
574
* // The `lazyLoad` function loads the final state definition
547
575
* {
548
- * name: 'parent.child ',
549
- * url: '/child ',
550
- * lazyLoad: () => System.import('./child.state .js')
576
+ * name: 'parent.** ',
577
+ * url: '/parent ',
578
+ * lazyLoad: () => System.import('./lazy.states .js')
551
579
* }
552
580
* ```
553
581
*
554
- * #### child.state .js
582
+ * #### Example: lazy.states .js
555
583
*
556
584
* This file is lazy loaded. It exports an array of states.
557
585
*
558
586
* ```js
559
587
* import {ChildComponent} from "./child.component.js";
588
+ * import {ParentComponent} from "./parent.component.js";
560
589
*
561
- * let childState = {
590
+ * // This fully defined state replaces the future state
591
+ * let parentState = {
562
592
* // the name should match the future state
593
+ * name: 'parent',
594
+ * url: '/parent/:parentId',
595
+ * component: ParentComponent,
596
+ * resolve: {
597
+ * parentData: ($transition$, ParentService) =>
598
+ * ParentService.get($transition$.params().parentId)
599
+ * }
600
+ * }
601
+ *
602
+ * let childState = {
563
603
* name: 'parent.child',
564
604
* url: '/child/:childId',
565
605
* params: {
566
- * id : "default"
606
+ * childId : "default"
567
607
* },
568
608
* resolve: {
569
609
* childData: ($transition$, ChildService) =>
@@ -572,19 +612,20 @@ export interface StateDeclaration {
572
612
* };
573
613
*
574
614
* // This array of states will be registered by the lazyLoad hook
575
- * let result = {
576
- * states: [ childState ]
615
+ * let lazyLoadResults = {
616
+ * states: [ parentState, childState ]
577
617
* };
578
618
*
579
- * export default result ;
619
+ * export default lazyLoadResults ;
580
620
* ```
581
621
*
582
622
* @param transition the [[Transition]] that is activating the future state
623
+ * @param state the [[StateDeclaration]] that the `lazyLoad` function is declared on
583
624
* @return a Promise to load the states.
584
625
* Optionally, if the promise resolves to a [[LazyLoadResult]],
585
626
* the states will be registered with the [[StateRegistry]].
586
627
*/
587
- lazyLoad ?: ( transition : Transition ) => Promise < LazyLoadResult > ;
628
+ lazyLoad ?: ( transition : Transition , state : StateDeclaration ) => Promise < LazyLoadResult > ;
588
629
589
630
/**
590
631
* @deprecated define individual parameters as [[ParamDeclaration.dynamic]]
0 commit comments