aboutsummaryrefslogtreecommitdiffstats
path: root/src/services.js
diff options
context:
space:
mode:
authorVojta Jina2010-11-15 01:10:16 +0000
committerMisko Hevery2010-11-15 21:55:37 -0800
commitcc749760fd59418433de5a055d1ca401f7500444 (patch)
treea6bc273b68b10515b9e00bc0b166c46d88748033 /src/services.js
parentb467a50bc75b7f4c0d9bcee521387eda460337bf (diff)
downloadangular.js-cc749760fd59418433de5a055d1ca401f7500444.tar.bz2
Added basic Services, which support @memberOf and @methodOf
Diffstat (limited to 'src/services.js')
-rw-r--r--src/services.js402
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];
}
};