Skip to content

Commit 67be0bd

Browse files
committed
docs($urlMatcherFactory): Type object & formatting
Adds documentation for the Type object, and misc. cleanup and improvement of UrlMatcher and $urlMatcherFactory docs.
1 parent a472b30 commit 67be0bd

File tree

1 file changed

+203
-21
lines changed

1 file changed

+203
-21
lines changed

src/urlMatcherFactory.js

+203-21
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
* * `'/files/*path'` - ditto.
4040
*
4141
* @param {string} pattern The pattern to compile into a matcher.
42-
* @param {config} config A configuration object hash:
42+
* @param {Object} config A configuration object hash:
4343
*
4444
* * `caseInsensitive` - `true` if URL matching should be case insensitive, otherwise `false`, the default value (for backward compatibility) is `false`.
4545
* * `strict` - `false` if matching against a URL with a trailing slash should be treated as equivalent to a URL without a trailing slash, the default value is `true`.
@@ -158,14 +158,14 @@ function UrlMatcher(pattern, config) {
158158
*
159159
* @example
160160
* The following two matchers are equivalent:
161-
* ```
161+
* <pre>
162162
* new UrlMatcher('/user/{id}?q').concat('/details?date');
163163
* new UrlMatcher('/user/{id}/details?q&date');
164-
* ```
164+
* </pre>
165165
*
166166
* @param {string} pattern The pattern to append.
167-
* @param {object} config An object hash of the configuration for the matcher.
168-
* @returns {ui.router.util.type:UrlMatcher} A matcher for the concatenated pattern.
167+
* @param {Object} config An object hash of the configuration for the matcher.
168+
* @returns {UrlMatcher} A matcher for the concatenated pattern.
169169
*/
170170
UrlMatcher.prototype.concat = function (pattern, config) {
171171
// Because order of search parameters is irrelevant, we can add our own search
@@ -191,10 +191,12 @@ UrlMatcher.prototype.toString = function () {
191191
* as optional.
192192
*
193193
* @example
194-
* ```
195-
* new UrlMatcher('/user/{id}?q&r').exec('/user/bob', { x:'1', q:'hello' });
196-
* // returns { id:'bob', q:'hello', r:null }
197-
* ```
194+
* <pre>
195+
* new UrlMatcher('/user/{id}?q&r').exec('/user/bob', {
196+
* x: '1', q: 'hello'
197+
* });
198+
* // returns { id: 'bob', q: 'hello', r: null }
199+
* </pre>
198200
*
199201
* @param {string} path The URL path to match, e.g. `$location.path()`.
200202
* @param {Object} searchParams URL search parameters, e.g. `$location.search()`.
@@ -251,7 +253,7 @@ UrlMatcher.prototype.parameters = function (param) {
251253
* types of this `UrlMatcher`.
252254
*
253255
* @param {Object} params The object hash of parameters to validate.
254-
* @returns {Boolean} Returns `true` if `params` validates, otherwise `false`.
256+
* @returns {boolean} Returns `true` if `params` validates, otherwise `false`.
255257
*/
256258
UrlMatcher.prototype.validates = function (params) {
257259
var result = true, isOptional, cfg, self = this;
@@ -276,10 +278,10 @@ UrlMatcher.prototype.validates = function (params) {
276278
* treated as empty strings.
277279
*
278280
* @example
279-
* ```
281+
* <pre>
280282
* new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' });
281283
* // returns '/user/bob?q=yes'
282-
* ```
284+
* </pre>
283285
*
284286
* @param {Object} values the values to substitute for the parameters in this pattern.
285287
* @returns {string} the formatted URL (path and optionally search part).
@@ -315,22 +317,98 @@ UrlMatcher.prototype.format = function (values) {
315317

316318
UrlMatcher.prototype.$types = {};
317319

318-
function Type(options) {
319-
extend(this, options);
320+
/**
321+
* @ngdoc object
322+
* @name ui.router.util.type:Type
323+
*
324+
* @description
325+
* Implements an interface to define custom parameter types that can be decoded from and encoded to
326+
* string parameters matched in a URL. Used by {@link ui.router.util.type:UrlMatcher `UrlMatcher`}
327+
* objects when matching or formatting URLs, or comparing or validating parameter values.
328+
*
329+
* See {@link ui.router.util.$urlMatcherFactory#methods_type `$urlMatcherFactory#type()`} for more
330+
* information on registering custom types.
331+
*
332+
* @param {Object} config A configuration object hash that includes any method in `Type`'s public
333+
* interface, and/or `pattern`, which should contain a custom regular expression used to match
334+
* string parameters originating from a URL.
335+
*
336+
* @property {RegExp} pattern The regular expression pattern used to match values of this type when
337+
* coming from a substring of a URL.
338+
*
339+
* @returns {Object} Returns a new `Type` object.
340+
*/
341+
function Type(config) {
342+
extend(this, config);
320343
}
321344

345+
/**
346+
* @ngdoc function
347+
* @name ui.router.util.type:Type#is
348+
* @methodOf ui.router.util.type:Type
349+
*
350+
* @description
351+
* Detects whether a value is of a particular type. Accepts a native (decoded) value
352+
* and determines whether it matches the current `Type` object.
353+
*
354+
* @param {*} val The value to check.
355+
* @param {string} key Optional. If the type check is happening in the context of a specific
356+
* {@link ui.router.util.type:UrlMatcher `UrlMatcher`} object, this is the name of the
357+
* parameter in which `val` is stored. Can be used for meta-programming of `Type` objects.
358+
* @returns {Boolean} Returns `true` if the value matches the type, otherwise `false`.
359+
*/
322360
Type.prototype.is = function(val, key) {
323361
return true;
324362
};
325363

364+
/**
365+
* @ngdoc function
366+
* @name ui.router.util.type:Type#encode
367+
* @methodOf ui.router.util.type:Type
368+
*
369+
* @description
370+
* Encodes a custom/native type value to a string that can be embedded in a URL. Note that the
371+
* return value does *not* need to be URL-safe (i.e. passed through `encodeURIComponent()`), it
372+
* only needs to be a representation of `val` that has been coerced to a string.
373+
*
374+
* @param {*} val The value to encode.
375+
* @param {string} key The name of the parameter in which `val` is stored. Can be used for
376+
* meta-programming of `Type` objects.
377+
* @returns {string} Returns a string representation of `val` that can be encoded in a URL.
378+
*/
326379
Type.prototype.encode = function(val, key) {
327380
return val;
328381
};
329382

383+
/**
384+
* @ngdoc function
385+
* @name ui.router.util.type:Type#decode
386+
* @methodOf ui.router.util.type:Type
387+
*
388+
* @description
389+
* Converts a string URL parameter value to a custom/native value.
390+
*
391+
* @param {string} val The URL parameter value to decode.
392+
* @param {string} key The name of the parameter in which `val` is stored. Can be used for
393+
* meta-programming of `Type` objects.
394+
* @returns {*} Returns a custom representation of the URL parameter value.
395+
*/
330396
Type.prototype.decode = function(val, key) {
331397
return val;
332398
};
333399

400+
/**
401+
* @ngdoc function
402+
* @name ui.router.util.type:Type#equals
403+
* @methodOf ui.router.util.type:Type
404+
*
405+
* @description
406+
* Determines whether two decoded values are equivalent.
407+
*
408+
* @param {*} a A value to compare against.
409+
* @param {*} b A value to compare against.
410+
* @returns {Boolean} Returns `true` if the values are equivalent/equal, otherwise `false`.
411+
*/
334412
Type.prototype.equals = function(a, b) {
335413
return a == b;
336414
};
@@ -347,8 +425,8 @@ Type.prototype.pattern = /.*/;
347425
* @name ui.router.util.$urlMatcherFactory
348426
*
349427
* @description
350-
* Factory for {@link ui.router.util.type:UrlMatcher} instances. The factory is also available to providers
351-
* under the name `$urlMatcherFactoryProvider`.
428+
* Factory for {@link ui.router.util.type:UrlMatcher `UrlMatcher`} instances. The factory
429+
* is also available to providers under the name `$urlMatcherFactoryProvider`.
352430
*/
353431
function $UrlMatcherFactory() {
354432

@@ -413,7 +491,7 @@ function $UrlMatcherFactory() {
413491
* @description
414492
* Defines whether URL matching should be case sensitive (the default behavior), or not.
415493
*
416-
* @param {bool} value `false` to match URL in a case sensitive manner; otherwise `true`;
494+
* @param {boolean} value `false` to match URL in a case sensitive manner; otherwise `true`;
417495
*/
418496
this.caseInsensitive = function(value) {
419497
isCaseInsensitive = value;
@@ -427,7 +505,7 @@ function $UrlMatcherFactory() {
427505
* @description
428506
* Defines whether URLs should match trailing slashes, or not (the default behavior).
429507
*
430-
* @param {bool} value `false` to match trailing slashes in URLs, otherwise `true`.
508+
* @param {boolean} value `false` to match trailing slashes in URLs, otherwise `true`.
431509
*/
432510
this.strictMode = function(value) {
433511
isStrictMode = value;
@@ -439,11 +517,11 @@ function $UrlMatcherFactory() {
439517
* @methodOf ui.router.util.$urlMatcherFactory
440518
*
441519
* @description
442-
* Creates a {@link ui.router.util.type:UrlMatcher} for the specified pattern.
520+
* Creates a {@link ui.router.util.type:UrlMatcher `UrlMatcher`} for the specified pattern.
443521
*
444522
* @param {string} pattern The URL pattern.
445-
* @param {object} config The config object hash.
446-
* @returns {ui.router.util.type:UrlMatcher} The UrlMatcher.
523+
* @param {Object} config The config object hash.
524+
* @returns {UrlMatcher} The UrlMatcher.
447525
*/
448526
this.compile = function (pattern, config) {
449527
return new UrlMatcher(pattern, extend(getDefaultConfig(), config));
@@ -473,6 +551,110 @@ function $UrlMatcherFactory() {
473551
return result;
474552
};
475553

554+
/**
555+
* @ngdoc function
556+
* @name ui.router.util.$urlMatcherFactory#type
557+
* @methodOf ui.router.util.$urlMatcherFactory
558+
*
559+
* @description
560+
* Registers a custom {@link ui.router.util.type:Type `Type`} object that can be used to
561+
* generate URLs with typed parameters.
562+
*
563+
* @param {string} name The type name.
564+
* @param {Object|Function} def The type definition. See
565+
* {@link ui.router.util.type:Type `Type`} for information on the values accepted.
566+
*
567+
* @returns {Object} Returns `$urlMatcherFactoryProvider`.
568+
*
569+
* @example
570+
* This is a simple example of a custom type that encodes and decodes items from an
571+
* array, using the array index as the URL-encoded value:
572+
*
573+
* <pre>
574+
* var list = ['John', 'Paul', 'George', 'Ringo'];
575+
*
576+
* $urlMatcherFactoryProvider.type('listItem', {
577+
* encode: function(item) {
578+
* // Represent the list item in the URL using its corresponding index
579+
* return list.indexOf(item);
580+
* },
581+
* decode: function(item) {
582+
* // Look up the list item by index
583+
* return list[parseInt(item, 10)];
584+
* },
585+
* is: function(item) {
586+
* // Ensure the item is valid by checking to see that it appears
587+
* // in the list
588+
* return list.indexOf(item) > -1;
589+
* }
590+
* });
591+
*
592+
* $stateProvider.state('list', {
593+
* url: "/list/{item:listItem}",
594+
* controller: function($scope, $stateParams) {
595+
* console.log($stateParams.item);
596+
* }
597+
* });
598+
*
599+
* // ...
600+
*
601+
* // Changes URL to '/list/3', logs "Ringo" to the console
602+
* $state.go('list', { item: "Ringo" });
603+
* </pre>
604+
*
605+
* This is a more complex example of a type that relies on dependency injection to
606+
* interact with services, and uses the parameter name from the URL to infer how to
607+
* handle encoding and decoding parameter values:
608+
*
609+
* <pre>
610+
* // Defines a custom type that gets a value from a service,
611+
* // where each service gets different types of values from
612+
* // a backend API:
613+
* $urlMatcherFactoryProvider.type('dbObject', function(Users, Posts) {
614+
*
615+
* // Matches up services to URL parameter names
616+
* var services = {
617+
* user: Users,
618+
* post: Posts
619+
* };
620+
*
621+
* return {
622+
* encode: function(object) {
623+
* // Represent the object in the URL using its unique ID
624+
* return object.id;
625+
* },
626+
* decode: function(value, key) {
627+
* // Look up the object by ID, using the parameter
628+
* // name (key) to call the correct service
629+
* return services[key].findById(value);
630+
* },
631+
* is: function(object, key) {
632+
* // Check that object is a valid dbObject
633+
* return angular.isObject(object) && object.id && services[key];
634+
* }
635+
* equals: function(a, b) {
636+
* // Check the equality of decoded objects by comparing
637+
* // their unique IDs
638+
* return a.id === b.id;
639+
* }
640+
* };
641+
* });
642+
*
643+
* // In a config() block, you can then attach URLs with
644+
* // type-annotated parameters:
645+
* $stateProvider.state('users', {
646+
* url: "/users",
647+
* // ...
648+
* }).state('users.item', {
649+
* url: "/{user:dbObject}",
650+
* controller: function($scope, $stateParams) {
651+
* // $stateParams.user will now be an object returned from
652+
* // the Users service
653+
* },
654+
* // ...
655+
* });
656+
* </pre>
657+
*/
476658
this.type = function (name, def) {
477659
if (!isDefined(def)) return UrlMatcher.prototype.$types[name];
478660
typeQueue.push({ name: name, def: def });

0 commit comments

Comments
 (0)