@@ -454,7 +454,7 @@ function $UrlMatcherFactory() {
454
454
}
455
455
}
456
456
457
- var $types , enqueue = true , typeQueue = [ ] , injector , defaultTypes = {
457
+ var $types = { } , enqueue = true , typeQueue = [ ] , injector , defaultTypes = {
458
458
"searchParam" : {
459
459
encode : normalizeStringOrArray ,
460
460
decode : normalizeStringOrArray ,
@@ -610,8 +610,11 @@ function $UrlMatcherFactory() {
610
610
* generate URLs with typed parameters.
611
611
*
612
612
* @param {string } name The type name.
613
- * @param {Object|Function } def The type definition. See
613
+ * @param {Object|Function } definition The type definition. See
614
614
* {@link ui.router.util.type:Type `Type`} for information on the values accepted.
615
+ * @param {Object|Function } definitionFn (optional) A function that is injected before the app
616
+ * runtime starts. The result of this function is merged into the existing `definition`.
617
+ * See {@link ui.router.util.type:Type `Type`} for information on the values accepted.
615
618
*
616
619
* @returns {Object } Returns `$urlMatcherFactoryProvider`.
617
620
*
@@ -659,7 +662,7 @@ function $UrlMatcherFactory() {
659
662
* // Defines a custom type that gets a value from a service,
660
663
* // where each service gets different types of values from
661
664
* // a backend API:
662
- * $urlMatcherFactoryProvider.type('dbObject', function(Users, Posts) {
665
+ * $urlMatcherFactoryProvider.type('dbObject', {}, function(Users, Posts) {
663
666
*
664
667
* // Matches up services to URL parameter names
665
668
* var services = {
@@ -704,21 +707,35 @@ function $UrlMatcherFactory() {
704
707
* });
705
708
* </pre>
706
709
*/
707
- this . type = function ( name , def ) {
708
- if ( ! isDefined ( def ) ) {
709
- if ( ! isDefined ( $types ) ) throw new Error ( "Please wait until runtime to retrieve types." ) ;
710
- return $types [ name ] ;
710
+ this . type = function ( name , definition , definitionFn ) {
711
+ if ( ! isDefined ( definition ) ) return $types [ name ] ;
712
+ if ( $types . hasOwnProperty ( name ) ) throw new Error ( "A type named '" + name + "' has already been defined." ) ;
713
+
714
+ $types [ name ] = new Type ( definition ) ;
715
+ if ( definitionFn ) {
716
+ typeQueue . push ( { name : name , def : definitionFn } ) ;
717
+ if ( ! enqueue ) flushTypeQueue ( ) ;
711
718
}
712
- typeQueue . push ( { name : name , def : def } ) ;
713
- if ( ! enqueue ) flushTypeQueue ( ) ;
714
719
return this ;
715
720
} ;
716
721
722
+ // `flushTypeQueue()` waits until `$urlMatcherFactory` is injected before invoking the queued `definitionFn`s
723
+ function flushTypeQueue ( ) {
724
+ while ( typeQueue . length ) {
725
+ var type = typeQueue . shift ( ) ;
726
+ if ( type . pattern ) throw new Error ( "You cannot override a type's .pattern at runtime." ) ;
727
+ angular . extend ( $types [ type . name ] , injector . invoke ( type . def ) ) ;
728
+ }
729
+ }
730
+
731
+ // Register default types. Store them in the prototype of $types.
732
+ forEach ( defaultTypes , function ( type , name ) { $types [ name ] = new Type ( type ) ; } ) ;
733
+ $types = inherit ( $types , { } ) ;
734
+
717
735
/* No need to document $get, since it returns this */
718
736
this . $get = [ '$injector' , function ( $injector ) {
719
737
injector = $injector ;
720
738
enqueue = false ;
721
- $types = { } ;
722
739
flushTypeQueue ( ) ;
723
740
724
741
forEach ( defaultTypes , function ( type , name ) {
@@ -727,19 +744,6 @@ function $UrlMatcherFactory() {
727
744
return this ;
728
745
} ] ;
729
746
730
- // To ensure proper order of operations in object configuration, and to allow internal
731
- // types to be overridden, `flushTypeQueue()` waits until `$urlMatcherFactory` is injected
732
- // before actually wiring up and assigning type definitions
733
- function flushTypeQueue ( ) {
734
- forEach ( typeQueue , function ( type ) {
735
- if ( $types [ type . name ] ) {
736
- throw new Error ( "A type named '" + type . name + "' has already been defined." ) ;
737
- }
738
- var def = new Type ( isInjectable ( type . def ) ? injector . invoke ( type . def ) : type . def ) ;
739
- $types [ type . name ] = def ;
740
- } ) ;
741
- }
742
-
743
747
this . Param = function Param ( id , type , config ) {
744
748
var self = this ;
745
749
var defaultValueConfig = getDefaultValueConfig ( config ) ;
0 commit comments