Importing the "storage" module gives you access to a root
storage object. Any property you assign to this object
in one request will be avialable in any subsequent requests.
The typical way to define a top-level property of
storage is to check if it's defined and – if not
– set it to some default value, as in the example below.
Performance Note: storage can be quite fast, depending on how it's used, but performance tuning is beyond the scope of this reference. We suggest that for starters you just do whatever is simplest for your app, and for help performance-tuning, ask for help in The AppJet Forums.
2
3
4
5
6
7
8
if (! storage.counter) {
storage.counter = 0;
}
storage.counter++;
printp("Hits to this page: ", storage.counter);
A StorableObject is an object that can be persisted between requests.
To create a StorableObject, call new StorableObject().
You can optionally pass any JavaScript object to the constructor, and the
properties and values of the object will become properties and values
of the newly-created StorableObject, as in
new StorableObject({username: "aiba", password: "sex"}).
StorableObjects are very similar to normal JavaScript objects, except that
StorableObjects can't have properties that are functions. Properties that
are objects must be StorableObjects, and assigning a normal JavaScript object
will cause a StorableObject to be created (in other words, storage.foo
= {a: 1} behaves like storage.foo = new StorableObject({a: 1})).
Once a StorableObject is constructed, it may be persisted in two different
ways: You can assign it as the property of another StorableObject, such as
the root StorableObject called storage. Or you can add it
to a StorableCollection.
| object | obj? |
An optional object
whose properties will be copied into the returned
StorableObject. obj cannot have any functions, and any
properties of obj's prototype are ignored. Any objects
that obj references will also be copied. (Note that
because properties are copied, any subsequent modifications
to obj will not be reflected in the returned
StorableObject).
|
- string id
2
3
4
5
var obj = new StorableObject();
obj.message = "Hi there!";
storage.foo = obj;
2
3
storage.foo = new StorableObject({message: "Hi there!"});
2
3
4
5
6
7
8
9
10
11
storage.people = new StorableCollection();
var person1 = new StorableObject({name: "Aaron", age: 25});
var person2 = new StorableObject({name: "David", age: 24});
var person3 = new StorableObject({name: "JD", age: 25});
storage.people.add(person1);
storage.people.add(person2);
storage.people.add(person3);
A StorableCollection is a way of grouping together many StorableObjects.
StorableObjects in a StorableCollection are not stored in any particular order,
but you can use the sort or sortBy methods to access the objects in order.
A collection usually contains objects of the same "type" in that they have a similar
set of properties, but this is not strictly required.
If you are familiar with SQL databases, a StorableCollection provides much of the same functionality that a table provides in SQL, and you can think of each StorableObject in the collection as analogous to a row in a SQL table. Unlike SQL tables, StorableCollections do not have pre-defined columns. You can add StorableObjects with any properties you want.
After a StorableCollection is created, you add StorableObjects
to it by calling StorableCollection.add(), as documented below.
StorableCollections are also StorableObjects. Therefore, each
StorableCollection has an "id" property, and may be retreived with a call to getStorable().
Usually, however, StorableCollections are assigned to properties of
the global storage object, as in the examples below.
- add(obj)
- remove(obj)
- filter(match)
- sort(compare)
- sortBy(propertyName1, propertyName2, etc)
- forEach(f)
- size()
- first()
- limit(n)
- skip(n)
- reverse()
- id() from StorableObject
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// A collection of books
storage.books = new StorableCollection();
// Here we add a new StorableObject to the collection
storage.books.add(new StorableObject({title: "Shantaram", author: "Gregory David Roberts" }));
// If you call add with an object that is not a StorableObject, it
// gets converted to a StorableObject. So this is a more compact way
// of doing the same thing.
storage.books.add({title: "Musashi", author: "Eiji Yoshikawa"});
storage.books.add({title: "Hackers & Painters", author: "Paul Graham"});
function printBook(book) {
printp(html("<i>", book.title, "</i> (by ", book.author, ")"));
}
// Print books sorted by their StorableObject creation date.
storage.books.sort().forEach(printBook);
print(html("<hr>"));
// Print books sorted alphabetically by title.
storage.books.sortBy("title").forEach(printBook);
print(html("<hr>"));
// Print books sorted reverse-alphabetically by author.
storage.books.sortBy("-author").forEach(printBook);
Each StorableObject or StorableCollection has an id that never changes, and this id can be used to refer to the object in a URL or form parameter.
| string | id | The id of the object to be gotten. |
| StorableObject |
The StorableObject whose id is id,
or undefined if no such object exists.
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import("storage");
if (! storage.things) {
storage.things = new StorableCollection();
storage.things.add({message: "Hello world!"});
}
if (! request.param("idToDisplay")) {
var firstId = storage.things.first().id;
// show a button that creates a request with idToDisplay = firstId
printp(new QuickButton("Show first thing.", {}, {idToDisplay: firstId}));
}
else {
// display the "foo" property of whatever object has an id of idToDisplay
printp(getStorable(request.param("idToDisplay")).message);
}
| object | obj |
The object to add to this collection. If
obj is not a StorableObject, a new StorableObject is
created from obj by passing it to the StorableObject
constructor, copying its properties.
|
| StorableObject | The added object. |
2
c.add({name: "John"});
| object | obj |
The object to remove from this collection. If
obj is a StorableObject, obj itself is
removed from this collection. If obj is an collection
or a view on a collection (such as one created by filter), then all objects
provided in that collection are removed. Finally, if
obj is just a plain object, then all members of this
collection that have the same properties and values as
obj are removed. Note: passing an {}
removes all objects form this collection.
|
2
c.remove({name: "John"});
Filters this collection based on a matching object.
Like other operations on StorableCollection, filter() returns a view of the collection. Views are temporary subsets of a collection which can be iterated over or chained with other StorableCollection operations.
filter is a "chainable" operation, along with sort(), sortBy(),
and limit(). For example, it is common to perform calls such as
storage.mycollection.filter(...).sort(...).forEach(...).
| object | match |
The object to base a filter on. The returned
view contains only those members of this StorableCollection whose
properties have the same value as the ones in
match. (Properties in the collection's members not
present in match are ignored.)
|
| A filtered view of this collection. |
2
3
4
5
6
7
8
9
10
11
12
13
14
15
storage.people.add({firstName: "Bob", lastName: "Smith", age: 30});
storage.people.add({firstName: "John", lastName: "Smith", age: 29});
storage.people.add({firstName: "John", lastName: "Sanders", age: 29});
storage.people.add({firstName: "John", lastName: "Jacobs", age: 29});
function printPerson(p) {
printp(p.firstName, " ", p.lastName, " (age: ", p.age, ")");
}
printp("Everyone with firstName John:");
storage.people.filter({firstName: "John"}).sortBy("lastName").forEach(printPerson);
printp("Everyone with lastName Smith:");
storage.people.filter({lastName: "Smith"}).sortBy("firstName").forEach(printPerson);
Returns a sorted view of this collection based on a sorting function, or by object creation date if no sorting function is given.
sort() does not modify the StorableCollection is is called on.
Instead, it returns a view of the StorableCollection, which can be further
sorted, limited, or iterated over.
sort() is a "chainable" operation:
it can be applied to other filtered, sorted, or limited views, as in
the example below.
| function | compare? |
As with the function argument to
Array.sort, If no sort function is passed in, the returned view is sorted by object creation time, oldest objects first. |
| A sorted view of this collection. |
2
3
4
function printPerson(p) { printp(p.name); }
storage.people.sort(ageCompare).forEach(printPerson);
Returns a sorted view of this collection based on a property name.
This is sometimes more convienent than calling the more general sort() method
and writing your own comparator function.
sortBy is a "chainable" operation: it can be applied to
other filtered, sorted, or limited views.
| string | propertyName1 | Which property to use to compare the collected objects on. Optionally prepend the property name with a "-" to reverse the sort order. |
| string | propertyName2 | A secondary property to further sort the objects. |
| string | etc | etc. |
| A sorted view of this collection. |
2
3
4
// secondarily by "firstName" property, ascending.
storage.people.sortBy("-lastName", "firstName").forEach(printp);
Executes a function once on each member of this collection.
| function | f |
The function to call on each member of this
collection. Returning false will cause forEach to
abort.
|
2
3
4
storage.mycollection.sort().reverse().forEach(function(o) {
printp("recent object: ", o);
});
| number | The size of this collection. |
| number | The first object in this collection. |
n elements of
this collection or view. Useful in combination with sort to get, for example, the
10 most recent items in a collection.
limit() is a
"chainable" operation: it can be applied to other filtered, sorted, or
limited views.
| number | n | How many elements to limit the new view to. |
| A limited view of this collection. |
Returns a view that skips the first n elements of this
collection or view.
skip() is a "chainable" operation: it
can be applied to other filtered, sorted, or limited views.
This is particularly useful for paginating elements in a storable
collection. If there are n elements per page, and you want to
display page p, then you can get a view of this page's elements
with collection.skip(n*(p-1)).limit(n), as in the example
below.
| number | n | How many elements to skip. |
A new view of this collection with the first n elements skipped.
|
2
3
4
5
var p = request.param("pageNum");
var n = 10; // items per page
var view = mycollection.sort().skip(n*(p-1)).limit(n);
view.forEach(printp);
Returns a view with the order of elements reversed.
reverse() is a "chainable" operation:
it can be applied to other filtered, sorted, or limited views.
| A new view of this collection |
getStorable.