model view controller - dojo pattern - when to use set/watch and when to use notify/observe? -
i'm struggling mvc pattern around stateful objects , observable stores. can't find clarity on when use 1 on , mixing them isn't clean i'd hoped. ah! insight how manage observable collection of stateful items?
if item.set("key", value) can item.watch("key", cb) observe-er isn't notify-ed.
i can item.watch(function() { state.notify(item, item.id); }) notify observer if observe-er calls set "query out of date, must observe() query prior data modifications'" error cannot reconcile.
i can decouple via settimeout it's not feeling good.
here's code show i'm trying:
crudify: function ( store, query, crud ) { var result; if ( !crud ) { crud = query; query = store; store = null; } if ( store ) { query = store.query( query ); } result = query.observe( function ( row, deleteindex, insertindex ) { var del = ( 0 <= deleteindex ), ins = ( 0 <= insertindex ); !del && ins && crud.c && crud.c( row ); del && ins && crud.u && crud.u( row ); del && !ins && crud.d && crud.d( row ); }, !!crud.u ); crud.c && array.foreach( query, crud.c ); return result; }
and have store wrapper (for layers) i'm hacking pieces trying observe-ers notified of data changes without getting errors:
addlayer: function ( item ) { var = this; that.store.add(item); item.watch && item.watch(function (name, prior, curr) { if (prior !== curr) { that._queue.push(item); // attempting eliminate queries indirectly update store (can't find source of error) infor.delay(20, "layerprocessorstorenotification", function () { that._queue.foreach(function (item) { that.store.notify(item, that.getlayerid(item)); }); that._queue = []; }); } }); return item; },
the delay method looks this:
delay: function ( timeout, id, callback ) { this.delays = this.delays || []; var delay = this.delays[id]; if ( delay ) { cleartimeout( delay ); } delay = settimeout( callback, timeout ); this.delays[id] = delay; },
i can item.watch(function() { state.notify(item, item.id); }) notify observer
i didn't have problems using pattern, but...
but if observe-er calls set "query out of date, must observe() query prior data modifications'" error cannot reconcile.
you shouldn't have watch
call notify
, have observe
call set
. choose 1 or other. otherwise you're setting infinite loop of callbacks.
the code below works me. change made crudify
function change array.foreach(query, crud.c)
query.foreach(crud.c)
.
<script type="text/javascript" src="../javascripts/dojo-release-1.9.3-src/dojo/dojo.js"></script> <script type="text/javascript"> window.stackoverflow = { crudify: function ( store, query, crud ) { var result; if ( !crud ) { crud = query; query = store; store = null; } if ( store ) { query = store.query( query ); } result = query.observe( function ( row, deleteindex, insertindex ) { console.log("observed"); var del = ( 0 <= deleteindex ), ins = ( 0 <= insertindex ); !del && ins && crud.c && crud.c( row ); del && ins && crud.u && crud.u( row ); del && !ins && crud.d && crud.d( row ); }, !!crud.u ); crud.c && query.foreach( crud.c ); return result; } }; require([ "dojo/store/memory", "dojo/store/observable", "dojo/stateful", "dojo/_base/json", "dojo/domready!" ], function(memory, observable, stateful, dojo){ var store = observable(new memory({ data: [] })); var rawdata = [ { id: 1, data: "a" }, { id: 2, data: "b" }, { id: 3, data: "c" }] var myquery = { id : 3 }; rawdata.foreach(function (obj, index) { statefulobj = new stateful(obj); statefulobj.watch(function(name, oldvalue, newvalue) { console.log("watched"); store.notify(statefulobj, statefulobj.id); }); store.put(statefulobj); }); window.settimeout(function() { // directly triggers observe() callback store.notify(store.get(3), 3); }, 2000); window.settimeout(function() { // triggers watch(), indirectly triggers observe() through notify() store.get(3).set("data", "sea?"); }, 4000); window.settimeout(function() { // calls no callbacks because doesn't match query store.put({ id: 2, data: "bee" }); }, 6000); window.settimeout(function() { // update triggers observe() store.put(new stateful({ id: 3, data: "see!?!" })); // note didn't set watch() on new object (see below) }, 8000); window.settimeout(function() { // whoops, doesn't trigger callback because forgot call watch() above store.get(3).set("data", "c4"); }, 10000); window.settimeout(function() { // observe() callback still works store.notify(store.get(3), 3); }, 12000); window.settimeout(function() { // deletion triggers observe() store.remove(3); }, 14000); stackoverflow.crudify( store, myquery, { u: function(obj) { console.log("observed update: obj: " + dojo.tojson(obj)); }, c: function(obj) { console.log("observed creation: obj: " + dojo.tojson(obj)); }, d: function(obj) { console.log("observed deletion: obj: " + dojo.tojson(obj)); } }); }); </script>
Comments
Post a Comment