source: Dev/trunk/src/client/dojox/data/AppStore.js @ 529

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

Added Dojo 1.9.3 release.

File size: 22.1 KB
Line 
1define(["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/atom/io/Connection"], function(dojo, dojox) {
2
3dojo.experimental("dojox.data.AppStore");
4
5var AppStore = dojo.declare("dojox.data.AppStore", null, {
6
7        // url: [public] string
8        //              So the parser can instantiate the store via markup.
9        url: "",
10       
11        // urlPreventCache: [public] boolean
12        //              Whether or not to pass the preventCache parameter to the connection
13        urlPreventCache: false,
14
15        // xmethod: [public] boolean
16        //              Whether to use X-Method-Override for PUT/DELETE.
17        xmethod: false,
18       
19        _atomIO: null,
20        _feed: null,
21        _requests: null,
22        _processing: null,
23       
24        _updates: null,
25        _adds: null,
26        _deletes: null,
27       
28        constructor: function(/*Object*/args){
29                // summary:
30                //              The APP data store.
31                // description:
32                //              The APP Store is instantiated either in markup or programmatically by supplying a
33                //              url of the Collection to be used.
34                // args:
35                //              An anonymous object to initialize properties.  It expects the following values:
36                //
37                //              - url:                          The url of the Collection to load.
38                //              - urlPreventCache:      Whether or not to append on cache prevention params (as defined by dojo.xhr*)
39               
40                if(args && args.url){
41                        this.url = args.url;
42                }
43                if(args && args.urlPreventCache){
44                        this.urlPreventCache = args.urlPreventCache;
45                }
46                if(!this.url){
47                        throw new Error("A URL is required to instantiate an APP Store object");
48                }
49        },
50       
51        _setFeed: function(feed, data){
52                // summary:
53                //              Sets the internal feed using a dojox.atom.io.model.Feed object.
54                // description:
55                //              Sets the internal feed using a dojox.atom.io.model.Feed object.  Also adds
56                //              a property to the entries to track that they belong to this store. It
57                //              also parses stored requests (since we were waiting on a callback) and
58                //              executes those as well.
59                // feed: dojox.atom.io.model.Feed object
60                //              The Feed to use for this data store.
61                // data: unused
62                //              Signature for this function is defined by AtomIO.getFeed, since this is a callback.
63                this._feed = feed;
64                var i;
65                for(i=0; i<this._feed.entries.length; i++){
66                        this._feed.entries[i].store = this;
67                }
68                if(this._requests){
69                        for(i=0; i<this._requests.length; i++){
70                                var request = this._requests[i];
71                                if(request.request && request.fh && request.eh){
72                                        this._finishFetchItems(request.request, request.fh, request.eh);
73                                }else if(request.clear){
74                                        this._feed = null;
75                                }else if(request.add){
76                                        this._feed.addEntry(request.add);
77                                }else if(request.remove){
78                                        this._feed.removeEntry(request.remove);
79                                }
80                        }
81                }
82                this._requests = null;
83        },
84       
85        _getAllItems: function(){
86                // summary:
87                //              Function to return all entries in the Feed as an array of items.
88                // description:
89                //              Function to return all entries in the Feed as an array of items.
90                // returns:
91                //              Array of all entries in the feed.
92                var items = [];
93                for(var i=0; i<this._feed.entries.length; i++){
94                        items.push(this._feed.entries[i]);
95                }
96                return items; //array
97        },
98       
99        _assertIsItem: function(/* item */ item){
100                // summary:
101                //              This function tests whether the item is an item.
102                // description:
103                //              This function tests whether the item passed in is indeed an item
104                //              in the store.
105                // item:
106                //              The item to test for being contained by the store.
107                if(!this.isItem(item)){
108                        throw new Error("This error message is provided when a function is called in the following form: "
109                                + "getAttribute(argument, attributeName).  The argument variable represents the member "
110                                + "or owner of the object. The error is created when an item that does not belong "
111                                + "to this store is specified as an argument.");
112                }
113        },
114
115        _assertIsAttribute: function(/* String */ attribute){
116                // summary:
117                //              This function tests whether the item is an attribute.
118                // description:
119                //              This function tests whether the item passed in is indeed a valid
120                //              'attribute' like type for the store.
121                // attribute:
122                //              The attribute to test for being contained by the store.
123                // returns:
124                //              Returns a boolean indicating whether this is a valid attribute.
125                if(typeof attribute !== "string"){
126                        throw new Error("The attribute argument must be a string. The error is created "
127                        + "when a different type of variable is specified such as an array or object.");
128                }
129
130                for(var key in dojox.atom.io.model._actions){
131                        if(key == attribute){
132                                return true;
133                        }
134                }
135                return false;
136        },
137       
138        _addUpdate: function(/* Object */ update){
139                // summary:
140                //              Internal function to add an updated entry to our updates array
141                // description:
142                //              Internal function to add an updated entry to our updates array
143                // update: dojox.atom.io.model.Entry object
144                //              The updated Entry we've changed.
145                if(!this._updates){
146                        this._updates = [update];
147                }else{
148                        this._updates.push(update);
149                }
150        },
151
152/***************************************
153     dojo/data/api/Read API
154***************************************/
155       
156        getValue: function(     /* item */ item,
157                                                /* attribute-name-string */ attribute,
158                                                /* value? */ defaultValue){
159                // summary:
160                //              See dojo/data/api/Read.getValue()
161                var values = this.getValues(item, attribute);
162                return (values.length > 0)?values[0]:defaultValue; // Object|Number|Boolean
163        },
164
165        getValues: function(/* item */ item,
166                                                /* attribute-name-string */ attribute){
167                // summary:
168                //              See dojo/data/api/Read.getValues()
169
170                this._assertIsItem(item);
171                var flag = this._assertIsAttribute(attribute);
172
173                if(flag){
174                        if((attribute === "author" || attribute === "contributor" || attribute === "link") && item[attribute+"s"]){
175                                return item[attribute+"s"];
176                        }
177                        if(attribute === "category" && item.categories){
178                                return item.categories;
179                        }
180                        if(item[attribute]){
181                                item = item[attribute];
182                                if(item.nodeType == "Content"){
183                                        return [item.value];
184                                }
185                                return [item] ;
186                        }
187                }
188                return []; //Array
189        },
190
191        getAttributes: function(/* item */ item){
192                // summary:
193                //              See dojo/data/api/Read.getAttributes()
194                this._assertIsItem(item);
195                var attributes = [];
196                for(var key in dojox.atom.io.model._actions){
197                        if(this.hasAttribute(item, key)){
198                                attributes.push(key);
199                        }
200                }
201                return attributes; //Array
202        },
203
204        hasAttribute: function( /* item */ item,
205                                                        /* attribute-name-string */ attribute){
206                // summary:
207                //              See dojo/data/api/Read.hasAttribute()
208                return this.getValues(item, attribute).length > 0;
209        },
210
211        containsValue: function(/* item */ item,
212                                                        /* attribute-name-string */ attribute,
213                                                        /* anything */ value){
214                // summary:
215                //              See dojo/data/api/Read.containsValue()
216                var regexp = undefined;
217                if(typeof value === "string"){
218                        regexp = dojo.data.util.filter.patternToRegExp(value, false);
219                }
220                return this._containsValue(item, attribute, value, regexp); //boolean.
221        },
222
223        _containsValue: function(       /* item */ item,
224                                                                /* attribute-name-string */ attribute,
225                                                                /* anything */ value,
226                                                                /* RegExp?*/ regexp,
227                                                                /* Boolean?*/ trim){
228                // summary:
229                //              Internal function for looking at the values contained by the item.
230                // description:
231                //              Internal function for looking at the values contained by the item.  This
232                //              function allows for denoting if the comparison should be case sensitive for
233                //              strings or not (for handling filtering cases where string case should not matter)
234                // item:
235                //              The data item to examine for attribute values.
236                // attribute:
237                //              The attribute to inspect.
238                // value:
239                //              The value to match.
240                // regexp:
241                //              Optional regular expression generated off value if value was of string type to handle wildcarding.
242                //              If present and attribute values are string, then it can be used for comparison instead of 'value'
243                var values = this.getValues(item, attribute);
244                for(var i = 0; i < values.length; ++i){
245                        var possibleValue = values[i];
246                        if(typeof possibleValue === "string" && regexp){
247                                if(trim){
248                                        possibleValue = possibleValue.replace(new RegExp(/^\s+/),""); // START
249                                        possibleValue = possibleValue.replace(new RegExp(/\s+$/),""); // END
250                                }
251                                possibleValue = possibleValue.replace(/\r|\n|\r\n/g, "");
252                                return (possibleValue.match(regexp) !== null);
253                        }else{
254                                //Non-string matching.
255                                if(value === possibleValue){
256                                        return true; // Boolean
257                                }
258                        }
259                }
260                return false; // Boolean
261        },
262
263        isItem: function(/* anything */ something){
264                // summary:
265                //              See dojo/data/api/Read.isItem()
266                return something && something.store && something.store === this; //boolean
267        },
268
269        isItemLoaded: function(/* anything */ something){
270                // summary:
271                //              See dojo/data/api/Read.isItemLoaded()
272                return this.isItem(something);
273        },
274
275        loadItem: function(/* Object */ keywordArgs){
276                // summary:
277                //              See dojo/data/api/Read.loadItem()
278                this._assertIsItem(keywordArgs.item);
279        },
280       
281        _fetchItems: function(request, fetchHandler, errorHandler){
282                // summary:
283                //              Fetch items (Atom entries) that match to a query
284                // description:
285                //              Fetch items (Atom entries) that match to a query
286                // request:
287                //              A request object
288                // fetchHandler:
289                //              A function to call for fetched items
290                // errorHandler:
291                //              A function to call on error
292                if(this._feed){
293                        this._finishFetchItems(request, fetchHandler, errorHandler);
294                }else{
295                        var flag = false;
296                        if(!this._requests){
297                                this._requests = [];
298                                flag = true;
299                        }
300                        this._requests.push({request: request, fh: fetchHandler, eh: errorHandler});
301                        if(flag){
302                                this._atomIO = new dojox.atom.io.Connection(false, this.urlPreventCache);
303                                this._atomIO.getFeed(this.url,this._setFeed, null, this);
304                        }
305                }
306        },
307               
308        _finishFetchItems: function(request, fetchHandler, errorHandler){
309                // summary:
310                //              Internal function for finishing a fetch request.
311                // description:
312                //              Internal function for finishing a fetch request.  Needed since the feed
313                //              might not have been loaded, so we finish the fetch in a callback.
314                // request:
315                //              A request object
316                // fetchHandler:
317                //              A function to call for fetched items
318                // errorHandler:
319                //              A function to call on error
320                var items = null;
321                var arrayOfAllItems = this._getAllItems();
322                if(request.query){
323                        var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false;
324                        items = [];
325
326                        //See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the
327                        //same value for each item examined.  Much more efficient.
328                        var regexpList = {};
329                        var key;
330                        var value;
331                        for(key in request.query){
332                                value = request.query[key]+'';
333                                if(typeof value === "string"){
334                                        regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);
335                                }
336                        }
337
338                        for(var i = 0; i < arrayOfAllItems.length; ++i){
339                                var match = true;
340                                var candidateItem = arrayOfAllItems[i];
341                                for(key in request.query){
342                                        value = request.query[key]+'';
343                                        if(!this._containsValue(candidateItem, key, value, regexpList[key], request.trim)){
344                                                match = false;
345                                        }
346                                }
347                                if(match){
348                                        items.push(candidateItem);
349                                }
350                        }
351                }else{
352                        // We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort
353                        // of the internal list so that multiple callers can get listsand sort without affecting each other.
354                        if(arrayOfAllItems.length> 0){
355                                items = arrayOfAllItems.slice(0,arrayOfAllItems.length);
356                        }
357                }
358                try{
359                        fetchHandler(items, request);
360                }catch(e){
361                        errorHandler(e, request);
362                }
363        },
364
365        getFeatures: function(){
366                // summary:
367                //              See dojo/data/api/Read.getFeatures()
368                return {
369                        'dojo.data.api.Read': true,
370                        'dojo.data.api.Write': true,
371                        'dojo.data.api.Identity': true
372                };
373        },
374       
375        close: function(/*dojo/data/api/Request|Object?*/ request){
376                // summary:
377                //              See dojo/data/api/Read.close()
378               
379                // nothing to do here!
380                this._feed = null;
381        },
382
383        getLabel: function(/* item */ item){
384                // summary:
385                //              See dojo/data/api/Read.getLabel()
386                if(this.isItem(item)){
387                        return this.getValue(item, "title", "No Title");
388                }
389                return undefined;
390        },
391
392        getLabelAttributes: function(/* item */ item){
393                // summary:
394                //              See dojo/data/api/Read.getLabelAttributes()
395                return ["title"];
396        },
397
398/***************************************
399     dojo/data/api/Identity API
400***************************************/
401
402        getIdentity: function(/* item */ item){
403                // summary:
404                //              See dojo/data/api/Identity.getIdentity()
405                this._assertIsItem(item);
406                return this.getValue(item, "id");
407        },
408
409        getIdentityAttributes: function(/* item */ item){
410                // summary:
411                //              See dojo/data/api/Identity.getIdentityAttributes()
412                return ["id"];
413        },
414
415        fetchItemByIdentity: function(keywordArgs){
416                // summary:
417                //              See dojo/data/api/Identity.fetchItemByIdentity()
418
419                this._fetchItems({query:{id:keywordArgs.identity}, onItem: keywordArgs.onItem, scope: keywordArgs.scope},
420                        function(items, request){
421                                var scope = request.scope;
422                                if(!scope){
423                                        scope = dojo.global;
424                                }
425                                if(items.length < 1){
426                                        request.onItem.call(scope, null);
427                                }else{
428                                        request.onItem.call(scope, items[0]);
429                                }
430                }, keywordArgs.onError);
431        },
432
433/***************************************
434     dojo/data/api/Identity API
435***************************************/
436
437        newItem: function(/* Object? */ keywordArgs){
438                // summary:
439                //              See dojo/data/api/Write.newItem()
440                var entry = new dojox.atom.io.model.Entry();
441                var value = null;
442                var temp = null;
443                var i;
444                for(var key in keywordArgs){
445                        if(this._assertIsAttribute(key)){
446                                value = keywordArgs[key];
447                                switch(key){
448                                        case "link":
449                                                for(i in value){
450                                                        temp = value[i];
451                                                        entry.addLink(temp.href,temp.rel,temp.hrefLang,temp.title,temp.type);
452                                                }
453                                                break;
454                                        case "author":
455                                                for(i in value){
456                                                        temp = value[i];
457                                                        entry.addAuthor(temp.name, temp.email, temp.uri);
458                                                }
459                                                break;
460                                        case "contributor":
461                                                for(i in value){
462                                                        temp = value[i];
463                                                        entry.addContributor(temp.name, temp.email, temp.uri);
464                                                }
465                                                break;
466                                        case "category":
467                                                for(i in value){
468                                                        temp = value[i];
469                                                        entry.addCategory(temp.scheme, temp.term, temp.label);
470                                                }
471                                                break;
472                                        case "icon":
473                                        case "id":
474                                        case "logo":
475                                        case "xmlBase":
476                                        case "rights":
477                                                entry[key] = value;
478                                                break;
479                                        case "updated":
480                                        case "published":
481                                        case "issued":
482                                        case "modified":
483                                                entry[key] = dojox.atom.io.model.util.createDate(value);
484                                                break;
485                                        case "content":
486                                        case "summary":
487                                        case "title":
488                                        case "subtitle":
489                                                entry[key] = new dojox.atom.io.model.Content(key);
490                                                entry[key].value = value;
491                                                break;
492                                        default:
493                                                entry[key] = value;
494                                                break;
495                                }
496                        }
497                }
498                entry.store = this;
499                entry.isDirty = true;
500
501                if(!this._adds){
502                        this._adds = [entry];
503                }else{
504                        this._adds.push(entry);
505                }
506
507                if(this._feed){
508                        this._feed.addEntry(entry);
509                }else{
510                        if(this._requests){
511                                this._requests.push({add:entry});
512                        }else{
513                                this._requests = [{add:entry}];
514                                this._atomIO = new dojox.atom.io.Connection(false, this.urlPreventCache);
515                                this._atomIO.getFeed(this.url,dojo.hitch(this,this._setFeed));
516                        }
517                }
518                return true;
519        },
520
521        deleteItem: function(/* item */ item){
522                // summary:
523                //              See dojo/data/api/Write.deleteItem()
524                this._assertIsItem(item);
525
526                if(!this._deletes){
527                        this._deletes = [item];
528                }else{
529                        this._deletes.push(item);
530                }
531
532                if(this._feed){
533                        this._feed.removeEntry(item);
534                }else{
535                        if(this._requests){
536                                this._requests.push({remove:item});
537                        }else{
538                                this._requests = [{remove:item}];
539                                this._atomIO = new dojox.atom.io.Connection(false, this.urlPreventCache);
540                                this._atomIO.getFeed(this.url,dojo.hitch(this,this._setFeed));
541                        }
542                }
543                item = null;
544                return true;
545        },
546
547        setValue: function(     /* item */ item,
548                                                /* string */ attribute,
549                                                /* almost anything */ value){
550                // summary:
551                //              See dojo/data/api/Write.setValue()
552                this._assertIsItem(item);
553               
554                var update = {item: item};
555                if(this._assertIsAttribute(attribute)){
556                        switch(attribute){
557                                case "link":
558                                        update.links = item.links;
559                                        this._addUpdate(update);
560                                        item.links = null;
561                                        item.addLink(value.href,value.rel,value.hrefLang,value.title,value.type);
562                                        item.isDirty = true;
563                                        return true;
564                                case "author":
565                                        update.authors = item.authors;
566                                        this._addUpdate(update);
567                                        item.authors = null;
568                                        item.addAuthor(value.name, value.email, value.uri);
569                                        item.isDirty = true;
570                                        return true;
571                                case "contributor":
572                                        update.contributors = item.contributors;
573                                        this._addUpdate(update);
574                                        item.contributors = null;
575                                        item.addContributor(value.name, value.email, value.uri);
576                                        item.isDirty = true;
577                                        return true;
578                                case "category":
579                                        update.categories = item.categories;
580                                        this._addUpdate(update);
581                                        item.categories = null;
582                                        item.addCategory(value.scheme, value.term, value.label);
583                                        item.isDirty = true;
584                                        return true;
585                                case "icon":
586                                case "id":
587                                case "logo":
588                                case "xmlBase":
589                                case "rights":
590                                        update[attribute] = item[attribute];
591                                        this._addUpdate(update);
592                                        item[attribute] = value;
593                                        item.isDirty = true;
594                                        return true;
595                                case "updated":
596                                case "published":
597                                case "issued":
598                                case "modified":
599                                        update[attribute] = item[attribute];
600                                        this._addUpdate(update);
601                                        item[attribute] = dojox.atom.io.model.util.createDate(value);
602                                        item.isDirty = true;
603                                        return true;
604                                case "content":
605                                case "summary":
606                                case "title":
607                                case "subtitle":
608                                        update[attribute] = item[attribute];
609                                        this._addUpdate(update);
610                                        item[attribute] = new dojox.atom.io.model.Content(attribute);
611                                        item[attribute].value = value;
612                                        item.isDirty = true;
613                                        return true;
614                                default:
615                                        update[attribute] = item[attribute];
616                                        this._addUpdate(update);
617                                        item[attribute] = value;
618                                        item.isDirty = true;
619                                        return true;
620                        }
621                }
622                return false;
623        },
624
625        setValues: function(/* item */ item,
626                                                /* string */ attribute,
627                                                /* array */ values){
628                // summary:
629                //              See dojo/data/api/Write.setValues()
630                if(values.length === 0){
631                        return this.unsetAttribute(item, attribute);
632                }
633                this._assertIsItem(item);
634               
635                var update = {item: item};
636                var value;
637                var i;
638                if(this._assertIsAttribute(attribute)){
639                        switch(attribute){
640                                case "link":
641                                        update.links = item.links;
642                                        item.links = null;
643                                        for(i in values){
644                                                value = values[i];
645                                                item.addLink(value.href,value.rel,value.hrefLang,value.title,value.type);
646                                        }
647                                        item.isDirty = true;
648                                        return true;
649                                case "author":
650                                        update.authors = item.authors;
651                                        item.authors = null;
652                                        for(i in values){
653                                                value = values[i];
654                                                item.addAuthor(value.name, value.email, value.uri);
655                                        }
656                                        item.isDirty = true;
657                                        return true;
658                                case "contributor":
659                                        update.contributors = item.contributors;
660                                        item.contributors = null;
661                                        for(i in values){
662                                                value = values[i];
663                                                item.addContributor(value.name, value.email, value.uri);
664                                        }
665                                        item.isDirty = true;
666                                        return true;
667                                case "categories":
668                                        update.categories = item.categories;
669                                        item.categories = null;
670                                        for(i in values){
671                                                value = values[i];
672                                                item.addCategory(value.scheme, value.term, value.label);
673                                        }
674                                        item.isDirty = true;
675                                        return true;
676                                case "icon":
677                                case "id":
678                                case "logo":
679                                case "xmlBase":
680                                case "rights":
681                                        update[attribute] = item[attribute];
682                                        item[attribute] = values[0];
683                                        item.isDirty = true;
684                                        return true;
685                                case "updated":
686                                case "published":
687                                case "issued":
688                                case "modified":
689                                        update[attribute] = item[attribute];
690                                        item[attribute] = dojox.atom.io.model.util.createDate(values[0]);
691                                        item.isDirty = true;
692                                        return true;
693                                case "content":
694                                case "summary":
695                                case "title":
696                                case "subtitle":
697                                        update[attribute] = item[attribute];
698                                        item[attribute] = new dojox.atom.io.model.Content(attribute);
699                                        item[attribute].values[0] = values[0];
700                                        item.isDirty = true;
701                                        return true;
702                                default:
703                                        update[attribute] = item[attribute];
704                                        item[attribute] = values[0];
705                                        item.isDirty = true;
706                                        return true;
707                        }
708                }
709                this._addUpdate(update);
710                return false;
711        },
712
713        unsetAttribute: function(       /* item */ item,
714                                                                /* string */ attribute){
715                // summary:
716                //              See dojo/data/api/Write.unsetAttribute()
717                this._assertIsItem(item);
718                if(this._assertIsAttribute(attribute)){
719                        if(item[attribute] !== null){
720                                var update = {item: item};
721                                switch(attribute){
722                                        case "author":
723                                        case "contributor":
724                                        case "link":
725                                                update[attribute+"s"] = item[attribute+"s"];
726                                                break;
727                                        case "category":
728                                                update.categories = item.categories;
729                                                break;
730                                        default:
731                                                update[attribute] = item[attribute];
732                                                break;
733                                }
734                                item.isDirty = true;
735                                item[attribute] = null;
736                                this._addUpdate(update);
737                                return true;
738                        }
739                }
740                return false; // boolean
741        },
742
743        save: function(/* object */ keywordArgs){
744                // summary:
745                //              See dojo/data/api/Write.save()
746                // keywordArgs:
747                // |    {
748                // |            onComplete: function
749                // |            onError: function
750                // |            scope: object
751                // |    }
752                var i;
753                for(i in this._adds){
754                        this._atomIO.addEntry(this._adds[i], null, function(){}, keywordArgs.onError, false, keywordArgs.scope);
755                }
756                       
757                this._adds = null;
758               
759                for(i in this._updates){
760                        this._atomIO.updateEntry(this._updates[i].item, function(){}, keywordArgs.onError, false, this.xmethod, keywordArgs.scope);
761                }
762                       
763                this._updates = null;
764               
765                for(i in this._deletes){
766                        this._atomIO.removeEntry(this._deletes[i], function(){}, keywordArgs.onError, this.xmethod, keywordArgs.scope);
767                }
768                       
769                this._deletes = null;
770               
771                this._atomIO.getFeed(this.url,dojo.hitch(this,this._setFeed));
772               
773                if(keywordArgs.onComplete){
774                        var scope = keywordArgs.scope || dojo.global;
775                        keywordArgs.onComplete.call(scope);
776                }
777        },
778
779        revert: function(){
780                // summary:
781                //              See dojo/data/api/Write.revert()
782                var i;
783                for(i in this._adds){
784                        this._feed.removeEntry(this._adds[i]);
785                }
786                       
787                this._adds = null;
788               
789                var update, item, key;
790                for(i in this._updates){
791                        update = this._updates[i];
792                        item = update.item;
793                        for(key in update){
794                                if(key !== "item"){
795                                        item[key] = update[key];
796                                }
797                        }
798                }
799                this._updates = null;
800               
801                for(i in this._deletes){
802                        this._feed.addEntry(this._deletes[i]);
803                }
804                this._deletes = null;
805                return true;
806        },
807
808        isDirty: function(/* item? */ item){
809                // summary:
810                //              See dojo/data/api/Write.isDirty()
811                if(item){
812                        this._assertIsItem(item);
813                        return item.isDirty?true:false; //boolean
814                }
815                return (this._adds !== null || this._updates !== null); //boolean
816        }
817});
818
819dojo.extend(AppStore, dojo.data.util.simpleFetch);
820
821return AppStore;
822});
Note: See TracBrowser for help on using the repository browser.