javascript - ExtJS and Complex Save Operations -
extjs 4.1.0
update 6/6/13:
i have posted same question on sencha forums there hasn't been action. post more or less same, figured add here reference. still eager hear other community members' input on must common scenario in extjs application! http://www.sencha.com/forum/showthread.php?265358-complex-model-save-decoupling-data-and-updating-related-stores
update 7/16/13 (conclusion?)
the sencha post garnered little discussion. have decided put majority of load of complex save operations on application server , lazily refresh client stores need be. way can use own database wrapper encompass of transactions associated 1 complex domain object save guarantee atomicity. if saving new order
consists of saving order metadata, ten new instances of ordercontents
, potentially other information (addresses residing in other tables, new customer defined @ time of order creation, etc.) rather send payload application server, rather establish vulgar web of callbacks in client-side application code. data associated on one-to-one basis (such order
hasone address
) updated in success
callback of order.save()
operation. more complex data, such order
's contents, lazily handled calling contentstore.sync()
. i feel means guarantee atomicity without overwhelming number of client-callbacks
original post content
given overall disappointing functionality of saving association-heavy models, have ditched model associations in application , rely retrieving associated data myself. , good, unfortunately not resolve issue of saving data , updating extjs stores reflect changes on server.
take example saving order
object, composed of metadata ordercontents
i.e., parts on order. metadata ends in order_data
table in database, whereas contents end in order_contents
table each row linked parent order via order_id
column.
on client, retrieving contents order quite easy without need associations: var contents = this.getcontentsstore().query('order_id', 10).getrange()
. however, major flaw this hinging on content records being available in ordercontents
extjs store, apply if using associations not returned data server "main" object.
when saving order, send single request holds order's metadata (e.g., date, order number, supplier information, etc.) array of contents. these pieces of data picked apart , saved appropriate tables. makes enough sense me , works well.
all until comes returning saved/updated records application server. since request fired off calling orderobject.save()
, there nothing telling ordercontents
store new records available. handled automatically if instead add records store , call .sync()
, feel complicates saving process , rather handle decoupling on application server not mention, saving entire request quite nice well.
is there better way solve this? current solution follows...
var ordercontentsstore = this.getordercontentsstore(); myorderobject.save({ success: function(rec, op){ // new content records need added contents store! ordercontentsstore.add(rec.get('contents')); // array of ordercontent records ordercontentsstore.commitchanges(); // important } });
by calling commitchanges()
records added store considered clean (non-phantom, non-dirty) , no longer returned store's getmodifiedrecords()
method; rightly records should not passed application server in event of store.sync()
.
this approach seems kinda sloppy/hacky me haven't figured out better solution...
any input / thoughts appreciated!
update 8/26/13 found associated data indeed handled ext in create/update callback on model's proxy, finding data wasn't easy... see post here: extjs 4.1 - returning associated data in model.save() response
well, it's been couple months of having question open , feel there no magically awesome solution problem.
my solution follows...
when saving complex model (e.g., model would, or have few hasmany
associations), save 'parent' model includes associated data (as property/field on model!) , add (saved) associated data in aftersave/afterupdate callback.
take example purchaseorder
model hasmany
items
, hasone
address
. take note associated data included in model's properties, not passed server if solely exists in model's association store.
console.log(purchaseorder.getdata()); --- id: 0 order_num: "po12345" order_total: 100.95 customer_id: 1 order_address: object id: 0 ship_address_1: "123 awesome street" ship_address_2: "suite b" ship_city: "gnarlyville" ship_state: "vermont" ship_zip: "05401" ...etc... contents: array[2] 0: object id: 0 sku: "br10831" name: "super cool shiny thing" quantity: 5 sold_price: 84.23 1: object id: 0 sku: "br10311" name: "moderately fun paddle ball" quantity: 1 sold_price: 1.39
i have models
established purchaseorder.content
, purchaseorder.address
, yet data in purchaseorder
not instance of these models, rather data. again, ensure passed correctly application server.
once have object described above, send off application server via .save()
follows:
purchaseorder.save({ scope: me, success: me.afterordersave, failure: function(rec,op){ console.error('error saving purchase order', op); } }); afterordersave: function(record, operation){ var me = this; switch(operation.action){ case 'create': /** * add records appropriate stores. * since these records (from server) have id, * not marked dirty nor phantoms */ var savedrecord = operation.getresultset().records[0]; // has associated! me.getorderstore().add(savedrecord); me.getordercontentstore().add(savedrecord.getcontents()); //association! me.getorderaddressstore().add(savedrecord.getaddress()); // association! break; case 'update': // locate , update records response server break; } }
my application server receives purchaseorder
, handles saving data accordingly. not go gross details process largely dependent on own implementation. application framework loosely based on zend 1.11 (primarily leveraging zend_db
).
i feel best approach following reasons:
- no messy string of various model.save() callbacks on client
- only 1 request, easy manage
- atomicity handled on application server
- less round trips = less potential points of failure worry about
- if you're feeling lazy,
success
method of callback canreload
stores.
i let answer sit bit encourage discussion.
thanks reading!
Comments
Post a Comment