diff options
| author | Vojta Jina | 2010-11-15 01:10:16 +0000 |
|---|---|---|
| committer | Misko Hevery | 2010-11-15 21:55:37 -0800 |
| commit | cc749760fd59418433de5a055d1ca401f7500444 (patch) | |
| tree | a6bc273b68b10515b9e00bc0b166c46d88748033 /src/services.js | |
| parent | b467a50bc75b7f4c0d9bcee521387eda460337bf (diff) | |
| download | angular.js-cc749760fd59418433de5a055d1ca401f7500444.tar.bz2 | |
Added basic Services, which support @memberOf and @methodOf
Diffstat (limited to 'src/services.js')
| -rw-r--r-- | src/services.js | 402 |
1 files changed, 383 insertions, 19 deletions
diff --git a/src/services.js b/src/services.js index 9af69403..be442c20 100644 --- a/src/services.js +++ b/src/services.js @@ -8,11 +8,64 @@ function angularServiceInject(name, fn, inject, eager) { angularService(name, fn, {$inject:inject, $creation:eager}); } +/** + * @ngdoc service + * @name angular.service.$window + * + * @description + * Is reference to the browser's <b>window</b> object. While <b>window</b> + * is globally available in JavaScript, it causes testability problems, because + * it is a global variable. In <b><angular/></b> we always refer to it through the + * $window service, so it may be overriden, removed or mocked for testing. + * + * All expressions are evaluated with respect to current scope so they don't + * suffer from window globality. + * + * @example + <input ng:init="greeting='Hello World!'" type="text" name="greeting" /> + <button ng:click="$window.alert(greeting)">ALERT</button> + */ angularServiceInject("$window", bind(window, identity, window), [], EAGER_PUBLISHED); + +/** + * @ngdoc service + * @name angular.service.$document + * @requires $window + * + * @description + * Reference to the browser window.document, but wrapped into angular.element(). + */ angularServiceInject("$document", function(window){ return jqLite(window.document); }, ['$window'], EAGER_PUBLISHED); +/** + * @ngdoc service + * @name angular.service.$location + * @requires $browser + * + * @property {string} href + * @property {string} protocol + * @property {string} host + * @property {number} port + * @property {string} path + * @property {Object.<string|boolean>} search + * @property {string} hash + * @property {string} hashPath + * @property {Object.<string|boolean>} hashSearch + * + * @description + * Parses the browser location url and makes it available to your application. + * Any changes to the url are reflected into $location service and changes to + * $location are reflected to url. + * Notice that using browser's forward/back buttons changes the $location. + * + * @example + <a href="#">clear hash</a> | + <a href="#myPath?name=misko">test hash</a><br/> + <input type='text' name="$location.hash"/> + <pre>$location = {{$location}}</pre> + */ angularServiceInject("$location", function(browser) { var scope = this, location = {toString:toString, update:update, updateHash: updateHash}, @@ -39,6 +92,11 @@ angularServiceInject("$location", function(browser) { // PUBLIC METHODS /** + * @ngdoc method + * @name angular.service.$location#update + * @methodOf angular.service.$location + * + * @description * Update location object * Does not immediately update the browser * Browser is updated at the end of $eval() @@ -69,7 +127,12 @@ angularServiceInject("$location", function(browser) { } /** - * Update location hash + * @ngdoc method + * @name angular.service.$location#updateHash + * @methodOf angular.service.$location + * + * @description + * Update location hash part * @see update() * * @example @@ -99,9 +162,12 @@ angularServiceInject("$location", function(browser) { } /** + * @ngdoc method + * @name angular.service.$location#toString + * @methodOf angular.service.$location + * + * @description * Returns string representation - href - * - * @return {string} Location's href property */ function toString() { updateLocation(); @@ -224,23 +290,105 @@ angularServiceInject("$location", function(browser) { }, ['$browser'], EAGER_PUBLISHED); +/** + * @ngdoc service + * @name angular.service.$log + * @requires $window + * + * @description + * Is simple service for logging. Default implementation writes the message + * into the browser's console (if present). + * + * This is useful for debugging. + * + * @example + <p>Reload this page with open console, enter text and hit the log button...</p> + Message: + <input type="text" name="message" value="Hello World!"/> + <button ng:click="$log.log(message)">log</button> + <button ng:click="$log.warn(message)">warn</button> + <button ng:click="$log.info(message)">info</button> + <button ng:click="$log.error(message)">error</button> + */ angularServiceInject("$log", function($window){ var console = $window.console || {log: noop, warn: noop, info: noop, error: noop}, log = console.log || noop; return { + /** + * @ngdoc method + * @name angular.service.$log#log + * @methodOf angular.service.$log + * + * @description + * Write a log message + */ log: bind(console, log), + + /** + * @ngdoc method + * @name angular.service.$log#warn + * @methodOf angular.service.$log + * + * @description + * Write a warning message + */ warn: bind(console, console.warn || log), + + /** + * @ngdoc method + * @name angular.service.$log#info + * @methodOf angular.service.$log + * + * @description + * Write an information message + */ info: bind(console, console.info || log), + + /** + * @ngdoc method + * @name angular.service.$log#error + * @methodOf angular.service.$log + * + * @description + * Write an error message + */ error: bind(console, console.error || log) }; }, ['$window'], EAGER_PUBLISHED); +/** + * @ngdoc service + * @name angular.service.$exceptionHandler + * @requires $log + * + * @description + * Any uncaught exception in <angular/> is delegated to this service. + * The default implementation simply delegates to $log.error which logs it into + * the browser console. + * + * When unit testing it is useful to have uncaught exceptions propagate + * to the test so the test will fail rather than silently log the exception + * to the browser console. For this purpose you can override this service with + * a simple rethrow. + * + * @example + */ angularServiceInject('$exceptionHandler', function($log){ return function(e) { $log.error(e); }; }, ['$log'], EAGER_PUBLISHED); +/** + * @ngdoc service + * @name angular.service.$hover + * @requires $browser + * @requires $document + * + * @description + * + * @example + */ angularServiceInject("$hover", function(browser, document) { var tooltip, self = this, error, width = 300, arrowWidth = 10, body = jqLite(document[0].body); browser.hover(function(element, show){ @@ -287,9 +435,15 @@ angularServiceInject("$hover", function(browser, document) { }); }, ['$browser', '$document'], EAGER); - -/* Keeps references to all invalid widgets found during validation. Can be queried to find if there - * are invalid widgets currently displayed +/** + * @ngdoc service + * @name angular.service.$invalidWidgets + * + * @description + * Keeps references to all invalid widgets found during validation. + * Can be queried to find whether there are any invalid widgets currently displayed. + * + * @example */ angularServiceInject("$invalidWidgets", function(){ var invalidWidgets = []; @@ -373,7 +527,59 @@ function switchRouteMatcher(on, when, dstName) { return match ? dst : _null; } -angularServiceInject('$route', function(location){ +/** + * @ngdoc service + * @name angular.service.$route + * @requires $location + * + * @property {Object} current Name of the current route + * @property {Array.<Object>} routes List of configured routes + * + * @description + * Watches $location.hashPath and tries to map the hash to an existing route + * definition. It is used for deep-linking URLs to controllers and views (HTML partials). + * + * $route is typically used in conjunction with ng:include widget. + * + * @example +<p> + This example shows how changing the URL hash causes the <tt>$route</tt> + to match a route against the URL, and the <tt>[[ng:include]]</tt> pulls in the partial. + Try changing the URL in the input box to see changes. +</p> + +<script> + angular.service('myApp', function($route) { + $route.when('/Book/:bookId', {template:'rsrc/book.html', controller:BookCntl}); + $route.when('/Book/:bookId/ch/:chapterId', {template:'rsrc/chapter.html', controller:ChapterCntl}); + $route.onChange(function() { + $route.current.scope.params = $route.current.params; + }); + }, {$inject: ['$route']}); + + function BookCntl() { + this.name = "BookCntl"; + } + + function ChapterCntl() { + this.name = "ChapterCntl"; + } +</script> + +Chose: +<a href="#/Book/Moby">Moby</a> | +<a href="#/Book/Moby/ch/1">Moby: Ch1</a> | +<a href="#/Book/Gatsby">Gatsby</a> | +<a href="#/Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a><br/> +<input type="text" name="$location.hashPath" size="80" /> +<pre>$location={{$location}}</pre> +<pre>$route.current.template={{$route.current.template}}</pre> +<pre>$route.current.params={{$route.current.params}}</pre> +<pre>$route.current.scope.name={{$route.current.scope.name}}</pre> +<hr/> +<ng:include src="$route.current.template" scope="$route.current.scope"/> + */ +angularServiceInject('$route', function(location) { var routes = {}, onChange = [], matcher = switchRouteMatcher, @@ -381,8 +587,32 @@ angularServiceInject('$route', function(location){ dirty = 0, $route = { routes: routes, + + /** + * @ngdoc method + * @name angular.service.$route#onChange + * @methodOf angular.service.$route + * + * @param {function} fn Function that will be called on route change + * + * @description + * Register a handler function that will be called when route changes + */ onChange: bind(onChange, onChange.push), - when:function (path, params){ + + /** + * @ngdoc method + * @name angular.service.$route#when + * @methodOf angular.service.$route + * + * @param {string} path Route path (matched against $location.hash) + * @param {Object} params + * @returns {Object} route object + * + * @description + * Add new route + */ + when:function (path, params) { if (angular.isUndefined(path)) return routes; var route = routes[path]; if (!route) route = routes[path] = {}; @@ -415,6 +645,17 @@ angularServiceInject('$route', function(location){ return $route; }, ['$location'], EAGER_PUBLISHED); +/** + * @ngdoc service + * @name angular.service.$xhr + * @requires $browser + * @requires $error + * @requires $log + * + * @description + * + * @example + */ angularServiceInject('$xhr', function($browser, $error, $log){ var self = this; return function(method, url, post, callback){ @@ -446,12 +687,32 @@ angularServiceInject('$xhr', function($browser, $error, $log){ }; }, ['$browser', '$xhr.error', '$log']); +/** + * @ngdoc service + * @name angular.service.$xhr.error + * @requires $log + * + * @description + * + * @example + */ angularServiceInject('$xhr.error', function($log){ return function(request, response){ $log.error('ERROR: XHR: ' + request.url, request, response); }; }, ['$log']); +/** + * @ngdoc service + * @name angular.service.$xhr.bulk + * @requires $xhr + * @requires $xhr.error + * @requires $log + * + * @description + * + * @example + */ angularServiceInject('$xhr.bulk', function($xhr, $error, $log){ var requests = [], scope = this; @@ -502,6 +763,15 @@ angularServiceInject('$xhr.bulk', function($xhr, $error, $log){ return bulkXHR; }, ['$xhr', '$xhr.error', '$log']); +/** + * @ngdoc service + * @name angular.service.$xhr.cache + * @requires $xhr + * + * @description + * + * @example + */ angularServiceInject('$xhr.cache', function($xhr){ var inflight = {}, self = this; function cache(method, url, post, callback, verifyCache){ @@ -546,18 +816,74 @@ angularServiceInject('$xhr.cache', function($xhr){ return cache; }, ['$xhr.bulk']); +/** + * @ngdoc service + * @name angular.service.$resource + * @requires $xhr + * + * @description + * Is a factory which creates a resource object which lets you interact with + * <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" target="_blank">RESTful</a> + * server-side data sources. + * Resource object has action methods which provide high-level behaviors without + * the need to interact with the low level $xhr or XMLHttpRequest(). + * + * @example + <script> + function BuzzController($resource) { + this.Activity = $resource( + 'https://www.googleapis.com/buzz/v1/activities/:userId/:visibility/:activityId/:comments', + {alt:'json', callback:'JSON_CALLBACK'}, + {get:{method:'JSON', params:{visibility:'@self'}}, replies: {method:'JSON', params:{visibility:'@self', comments:'@comments'}}} + ); + } + + BuzzController.prototype = { + fetch: function() { + this.activities = this.Activity.get({userId:this.userId}); + }, + expandReplies: function(activity) { + activity.replies = this.Activity.replies({userId:this.userId, activityId:activity.id}); + } + }; + BuzzController.$inject = ['$resource']; + </script> + + <div ng:controller="BuzzController"> + <input name="userId" value="googlebuzz"/> + <button ng:click="fetch()">fetch</button> + <hr/> + <div ng:repeat="item in activities.data.items"> + <h1 style="font-size: 15px;"> + <img src="{{item.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/> + <a href="{{item.actor.profileUrl}}">{{item.actor.name}}</a> + <a href="#" ng:click="expandReplies(item)" style="float: right;">Expand replies: {{item.links.replies[0].count}}</a> + </h1> + {{item.object.content | html}} + <div ng:repeat="reply in item.replies.data.items" style="margin-left: 20px;"> + <img src="{{reply.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/> + <a href="{{reply.actor.profileUrl}}">{{reply.actor.name}}</a>: {{reply.content | html}} + </div> + </div> + </div> + */ angularServiceInject('$resource', function($xhr){ var resource = new ResourceFactory($xhr); return bind(resource, resource.route); }, ['$xhr.cache']); - /** - * $cookies service provides read/write access to the browser cookies. Currently only session - * cookies are supported. - * - * Only a simple Object is exposed and by adding or removing properties to/from this object, new - * cookies are created or deleted from the browser at the end of the current eval. + * @ngdoc service + * @name angular.service.$cookies + * @requires $browser + * + * @description + * Provides read/write access to browser's cookies. + * + * Only a simple Object is exposed and by adding or removing properties to/from + * this object, new cookies are created/deleted at the end of current $eval. + * + * @example */ angularServiceInject('$cookies', function($browser) { var rootScope = this, @@ -630,23 +956,61 @@ angularServiceInject('$cookies', function($browser) { } }, ['$browser'], EAGER_PUBLISHED); - /** - * $cookieStore provides a key-value (string-object) storage that is backed by session cookies. - * Objects put or retrieved from this storage are automatically serialized or deserialized. + * @ngdoc service + * @name angular.service.$cookieStore + * @requires $cookies + * + * @description + * Provides a key-value (string-object) storage, that is backed by session cookies. + * Objects put or retrieved from this storage are automatically serialized or + * deserialized by angular's toJson/fromJson. + * @example */ angularServiceInject('$cookieStore', function($store) { return { + /** + * @ngdoc method + * @name angular.service.$cookieStore#get + * @methodOf angular.service.$cookieStore + * + * @description + * Returns the value of given cookie key + * + * @param {string} key + * @returns Cookie value + */ get: function(/**string*/key) { return fromJson($store[key]); }, - put: function(/**string*/key, /**Object*/value) { + /** + * @ngdoc method + * @name angular.service.$cookieStore#put + * @methodOf angular.service.$cookieStore + * + * @description + * Sets a value for given cookie key + * + * @param {string} key + * @param {Object} value + */ + put: function(key, value) { $store[key] = toJson(value); }, - remove: function(/**string*/key) { + /** + * @ngdoc method + * @name angular.service.$cookieStore#remove + * @methodOf angular.service.$cookieStore + * + * @description + * Remove given cookie + * + * @param {string} key + */ + remove: function(key) { delete $store[key]; } }; |
