source: Dev/trunk/src/client/dojo/store/JsonRest.js @ 485

Last change on this file since 485 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 6.7 KB
Line 
1define(["../_base/xhr", "../_base/lang", "../json", "../_base/declare", "./util/QueryResults" /*=====, "./api/Store" =====*/
2], function(xhr, lang, JSON, declare, QueryResults /*=====, Store =====*/){
3
4// No base class, but for purposes of documentation, the base class is dojo/store/api/Store
5var base = null;
6/*===== base = Store; =====*/
7
8/*=====
9var __HeaderOptions = {
10                // headers: Object?
11                //              Additional headers to send along with the request.
12        },
13        __PutDirectives = declare(Store.PutDirectives, __HeaderOptions),
14        __QueryOptions = declare(Store.QueryOptions, __HeaderOptions);
15=====*/
16
17return declare("dojo.store.JsonRest", base, {
18        // summary:
19        //              This is a basic store for RESTful communicating with a server through JSON
20        //              formatted data. It implements dojo/store/api/Store.
21
22        constructor: function(options){
23                // summary:
24                //              This is a basic store for RESTful communicating with a server through JSON
25                //              formatted data.
26                // options: dojo/store/JsonRest
27                //              This provides any configuration information that will be mixed into the store
28                this.headers = {};
29                declare.safeMixin(this, options);
30        },
31
32        // headers: Object
33        //              Additional headers to pass in all requests to the server. These can be overridden
34        //              by passing additional headers to calls to the store.
35        headers: {},
36
37        // target: String
38        //              The target base URL to use for all requests to the server. This string will be
39        //              prepended to the id to generate the URL (relative or absolute) for requests
40        //              sent to the server
41        target: "",
42
43        // idProperty: String
44        //              Indicates the property to use as the identity property. The values of this
45        //              property should be unique.
46        idProperty: "id",
47
48        // sortParam: String
49        //              The query parameter to used for holding sort information. If this is omitted, than
50        //              the sort information is included in a functional query token to avoid colliding
51        //              with the set of name/value pairs.
52
53        // ascendingPrefix: String
54        //              The prefix to apply to sort attribute names that are ascending
55        ascendingPrefix: "+",
56
57        // descendingPrefix: String
58        //              The prefix to apply to sort attribute names that are ascending
59        descendingPrefix: "-",
60         
61
62        get: function(id, options){
63                // summary:
64                //              Retrieves an object by its identity. This will trigger a GET request to the server using
65                //              the url `this.target + id`.
66                // id: Number
67                //              The identity to use to lookup the object
68                // options: Object?
69                //              HTTP headers. For consistency with other methods, if a `headers` key exists on this object, it will be
70                //              used to provide HTTP headers instead.
71                // returns: Object
72                //              The object in the store that matches the given id.
73                options = options || {};
74                var headers = lang.mixin({ Accept: this.accepts }, this.headers, options.headers || options);
75                return xhr("GET", {
76                        url: this.target + id,
77                        handleAs: "json",
78                        headers: headers
79                });
80        },
81
82        // accepts: String
83        //              Defines the Accept header to use on HTTP requests
84        accepts: "application/javascript, application/json",
85
86        getIdentity: function(object){
87                // summary:
88                //              Returns an object's identity
89                // object: Object
90                //              The object to get the identity from
91                // returns: Number
92                return object[this.idProperty];
93        },
94
95        put: function(object, options){
96                // summary:
97                //              Stores an object. This will trigger a PUT request to the server
98                //              if the object has an id, otherwise it will trigger a POST request.
99                // object: Object
100                //              The object to store.
101                // options: __PutDirectives?
102                //              Additional metadata for storing the data.  Includes an "id"
103                //              property if a specific id is to be used.
104                // returns: dojo/_base/Deferred
105                options = options || {};
106                var id = ("id" in options) ? options.id : this.getIdentity(object);
107                var hasId = typeof id != "undefined";
108                return xhr(hasId && !options.incremental ? "PUT" : "POST", {
109                                url: hasId ? this.target + id : this.target,
110                                postData: JSON.stringify(object),
111                                handleAs: "json",
112                                headers: lang.mixin({
113                                        "Content-Type": "application/json",
114                                        Accept: this.accepts,
115                                        "If-Match": options.overwrite === true ? "*" : null,
116                                        "If-None-Match": options.overwrite === false ? "*" : null
117                                }, this.headers, options.headers)
118                        });
119        },
120
121        add: function(object, options){
122                // summary:
123                //              Adds an object. This will trigger a PUT request to the server
124                //              if the object has an id, otherwise it will trigger a POST request.
125                // object: Object
126                //              The object to store.
127                // options: __PutDirectives?
128                //              Additional metadata for storing the data.  Includes an "id"
129                //              property if a specific id is to be used.
130                options = options || {};
131                options.overwrite = false;
132                return this.put(object, options);
133        },
134
135        remove: function(id, options){
136                // summary:
137                //              Deletes an object by its identity. This will trigger a DELETE request to the server.
138                // id: Number
139                //              The identity to use to delete the object
140                // options: __HeaderOptions?
141                //              HTTP headers.
142                options = options || {};
143                return xhr("DELETE", {
144                        url: this.target + id,
145                        headers: lang.mixin({}, this.headers, options.headers)
146                });
147        },
148
149        query: function(query, options){
150                // summary:
151                //              Queries the store for objects. This will trigger a GET request to the server, with the
152                //              query added as a query string.
153                // query: Object
154                //              The query to use for retrieving objects from the store.
155                // options: __QueryOptions?
156                //              The optional arguments to apply to the resultset.
157                // returns: dojo/store/api/Store.QueryResults
158                //              The results of the query, extended with iterative methods.
159                options = options || {};
160
161                var headers = lang.mixin({ Accept: this.accepts }, this.headers, options.headers);
162
163                if(options.start >= 0 || options.count >= 0){
164                        headers.Range = headers["X-Range"] //set X-Range for Opera since it blocks "Range" header
165                                 = "items=" + (options.start || '0') + '-' +
166                                (("count" in options && options.count != Infinity) ?
167                                        (options.count + (options.start || 0) - 1) : '');
168                }
169                var hasQuestionMark = this.target.indexOf("?") > -1;
170                if(query && typeof query == "object"){
171                        query = xhr.objectToQuery(query);
172                        query = query ? (hasQuestionMark ? "&" : "?") + query: "";
173                }
174                if(options && options.sort){
175                        var sortParam = this.sortParam;
176                        query += (query || hasQuestionMark ? "&" : "?") + (sortParam ? sortParam + '=' : "sort(");
177                        for(var i = 0; i<options.sort.length; i++){
178                                var sort = options.sort[i];
179                                query += (i > 0 ? "," : "") + (sort.descending ? this.descendingPrefix : this.ascendingPrefix) + encodeURIComponent(sort.attribute);
180                        }
181                        if(!sortParam){
182                                query += ")";
183                        }
184                }
185                var results = xhr("GET", {
186                        url: this.target + (query || ""),
187                        handleAs: "json",
188                        headers: headers
189                });
190                results.total = results.then(function(){
191                        var range = results.ioArgs.xhr.getResponseHeader("Content-Range");
192                        return range && (range = range.match(/\/(.*)/)) && +range[1];
193                });
194                return QueryResults(results);
195        }
196});
197
198});
Note: See TracBrowser for help on using the repository browser.