Created
August 13, 2010 14:48
-
-
Save gbishop/522994 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Try Json Refs</title> | |
<style type="text/css"> | |
@import "http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/resources/dojo.css"; | |
@import "http://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit/themes/claro/claro.css"; | |
@import "http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojox/grid/resources/Grid.css"; | |
@import "http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojox/grid/resources/claroGrid.css"; | |
@import "style.css"; | |
@import "SetEditor.css"; | |
html, body, #content { | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
} | |
#editorGoesHere { | |
width: 400px; | |
height: 200px; | |
border: 1px solid black; | |
} | |
</style> | |
<script type="text/javascript"> | |
var djConfig = { | |
isDebug: false, | |
parseOnLoad: true, | |
baseUrl: './', | |
// map local widget namespaces -> paths relative to baseUrl | |
modulePaths: {'editor' : '.'} | |
}; | |
</script> | |
<script type="text/javascript" | |
src="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js"></script> | |
<script type="text/javascript" src="/libs/uow.js"></script> | |
<script type="text/javascript" src="tryJsonRefs.js"></script> | |
<script type="text/javascript"> | |
dojo.require('dijit.layout.BorderContainer'); | |
dojo.require('dijit.layout.ContentPane'); | |
</script> | |
</head> | |
<body class="claro"> | |
<div id="content" dojoType="dijit.layout.BorderContainer"> | |
<div id="top" dojoType="dijit.layout.ContentPane" region="top" splitter="false"> | |
<span>Set Editor</span> | |
<span class='nav_up'><img src='images/nav_up.png'/ ><a href='../index.html'>Back to Bigwords Index</a></span> | |
<span class='nav_back'><img src='images/nav_back.png'/ ><a href='index.html'>Back to Editor Index</a></span> | |
</div> | |
<div id="center" dojoType="dijit.layout.ContentPane" region="center"> | |
<div id="editorGoesHere"></div> | |
</div> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This is an experiment with Json Referencing in our uow databases which are derived from JsonRestStore. | |
When I run setup, it creates a database with a single record containing refs to the first record | |
in each game database. This is a prototype for sets in Big Words. | |
When I run restore, it reads the record and instantiates the refs. | |
From this experiment I have determined that the restoration happens when you call loadItem and | |
that the db's being referenced have to be open. But contrary to the examples I've seen, you don't | |
have to do the loadItem call on the store the ref points at; rather it is fine (thankfully) to do the | |
loadItem on the store containing the ref. | |
Further contradiction of the examples I have seen shows that for an object like: | |
item = { set: 'set1', game: { $ref: '/data/AlphabetSoupLessons/4c24c449229fe83f6e000062' } } | |
doing db.getValue(item, 'game') does NOT dereference game. It simply returns the ref. | |
But db.getValue(item.game, 'name') will dereference and return the name field of the game. | |
*/ | |
dojo.require('dojox.grid.DataGrid'); | |
// first a few helpers | |
/* let's try monkey patching MongoStore to use deferreds. | |
These are candidates for inclusion in MongoStore. | |
*/ | |
dojo.ready(function() { | |
var M = uow.data.MongoStore; | |
// deferred version of fetch | |
M.prototype.Fetch = function(args) { | |
var def = new dojo.Deferred(); | |
dojo.mixin(args, { | |
onComplete: def.callback, | |
onError: def.errback | |
}); | |
this.fetch(args); | |
return def; | |
}; | |
// deferred version of Save | |
M.prototype.Save = function() { | |
var def = new dojo.Deferred(); | |
this.save({ | |
onComplete: def.callback, | |
onError: def.errback | |
}); | |
return def; | |
}; | |
}); | |
/* try deleting all the records in a db the async way | |
Note that I don't appear to need an explicit Deferred in here. Just returning the result of | |
the "then" method appears to be enough. | |
*/ | |
function emptyDb(db) { | |
return db.Fetch( {query: {} } ).then(function(items) { | |
dojo.forEach(items, function(item) { | |
db.deleteItem(item); | |
}); | |
}); | |
} | |
/* open a store for each collection given, return the array of stores | |
It appears that I do need an explicit Deferred in here. I don't see how to otherwise deal | |
with the multiple deferred calls ending at different times. Is there some cool extension of | |
dojo.map to do this? Or some way to use dojo.when? | |
*/ | |
function openCollections(collections) { | |
var def = new dojo.Deferred(); | |
var toGo = collections.length; | |
var res = []; | |
dojo.forEach(collections, function(collection, index) { | |
uow.getDatabase({ | |
database: 'BigWords', | |
collection: collection, | |
mode: 'r' | |
}).then(function(db) { | |
res[index] = db; | |
toGo -= 1; | |
if (toGo <= 0) { | |
def.callback(res); | |
} | |
}); | |
}); | |
return def; | |
} | |
/* create a reference to first item in the given stores | |
How should I handle empty stores? res is going to have undef for those | |
*/ | |
function readFirst(stores) { | |
var def = new dojo.Deferred(); | |
var toGo = stores.length; | |
var res = []; | |
dojo.forEach(stores, function(store, index) { | |
store.Fetch({ | |
query: {}, | |
count: 1 | |
}).then(function(items) { | |
res[index] = store.target + items[0]._id; | |
toGo -= 1; | |
if (toGo <= 0) { | |
def.callback(res); | |
} | |
}); | |
}); | |
return def; | |
} | |
// game collections | |
allGames = ['TextTilesLessons', 'AlphabetSoupLessons', 'SortActivityLessons', | |
'SpellBinderLessons', 'WordBuilderLessons', 'SliceAndDiceLessons']; | |
/* the following functions are edited into the dojo.ready call at the bottom to choose which | |
one runs. You need to run setup first to build the store with the references. | |
*/ | |
// create an array of references in a database | |
function setup() { | |
var db1; | |
// step 1: get the 1st db | |
uow.getDatabase({database: 'BigWords', collection: 'gbTry'}).then(function(db) { | |
db1 = db; | |
// step 2: empty the 1st db | |
return emptyDb(db1); | |
}).then(function() { | |
// step 3: open the lesson dbs | |
return openCollections(allGames); | |
}).then(function(stores) { | |
// step 4: create a ref to the first item in each db | |
return readFirst(stores); | |
}).then(function(items) { | |
// step 5: save the references in db1 | |
dojo.forEach(items, function(item, i) { | |
db1.newItem({ set: 'set1', seq: i, game: { $ref: item } }); | |
}); | |
// step 6: save the new records | |
return db1.Save(); | |
}).then(function() { | |
console.log('setup all done'); | |
}); | |
} | |
// read the array of references and look at them | |
function restore() { | |
var db1; | |
// step 1: get the 1st db | |
uow.getDatabase({database: 'BigWords', collection: 'gbTry'}).then(function(db) { | |
db1 = db; | |
// setp 2: open the other stores (necessary for dereferencing to work) | |
return openCollections(allGames); | |
}).then(function(stores) { | |
// step 3: fetch the records | |
return db1.Fetch({ query: { set: 'set1' } }); | |
}).then(function(items) { | |
// step 4: load the individual array items | |
dojo.forEach(items, function(i) { | |
db1.loadItem( { | |
item: i.game, | |
onItem: function(item) { | |
console.log('loaded item', item); | |
} | |
}); | |
}); | |
}); | |
}; | |
/* experiment with getValue | |
Contrary to what the doc says in several places, db1.getValue(item, 'game') does NOT do the | |
dereference. I have to do db1.getvalue(item.game, 'name') to get the deference done. In other words | |
access a field in the deferred object. I can't see how the examples given in various blog posts | |
could possibly work given the code in getValue in dojox.data.ServiceStore.js. | |
*/ | |
function tryget() { | |
var db1; | |
// step 1: get the 1st db | |
uow.getDatabase({database: 'BigWords', collection: 'gbTry'}).then(function(db) { | |
db1 = db; | |
// setp 2: get the other stores | |
return openCollections(allGames); | |
}).then(function(stores) { | |
// step 3: fetch the records | |
return db1.Fetch({ query: { set: 'set1' } }); | |
}).then(function(items) { | |
console.log('rawrecord', items); | |
// get the first one | |
var item = items[0]; | |
console.log('game', item.game); // shows up as a $ref | |
console.log('loaded', db1.isItemLoaded(item.game)); // not loaded | |
console.log('wrong', db1.getValue(item, 'game')); | |
console.log('value', db1.getValue(item.game, 'name')); // does the deref | |
console.log('after deref', db1.getValue(item, 'game')); | |
}); | |
} | |
/* read the array of references and look at them with a grid | |
I need that formatter on game in order to force the lazy loading. The other possibility | |
is the dot-path extension to JsonRestStore.getValue proposed by medryx in his BeanStore. With | |
it we could just set field to 'game.name' | |
*/ | |
function display() { | |
var db1; | |
// step 1: get the 1st db | |
uow.getDatabase({database: 'BigWords', collection: 'gbTry'}).then(function(db) { | |
db1 = db; | |
// setp 2: get the other stores | |
return openCollections(allGames); | |
}).then(function(stores) { | |
// step 3: build the grid | |
var grid = new dojox.grid.DataGrid( { | |
store: db1, | |
structure: [ { name: 'Set', field: 'set', width: '20%' }, | |
{ name: 'Seq', field: 'seq', width: '20%' }, | |
{ name: 'Name', field: 'game', width: '60%', | |
formatter: function(game) { return db1.getValue(game, 'name'); } } ], | |
query: { set: 'set1' } | |
} ); | |
dojo.place(grid.domNode, 'editorGoesHere', 'only'); | |
grid.startup(); | |
dojo.connect(grid, 'onDblClick', function() { | |
var selected = grid.selection.getSelected()[0]; | |
console.log('selected', selected); | |
} ); | |
}); | |
}; | |
dojo.ready(display); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment