PDA

View Full Version : Ajax and data access layers



DaveC426913
22 Dec 2010, 8:02 AM
Help! My app is out of control. I'm now having to add another level of abstraction between the UI and the data access: dataObjects. And that means another layer of callbacks.

I'm adding this dataObjects layer because data access is at a premium: get everything once instead of one thing at a time. So there's some functionality I'll need in order to manipulate the list of data (for example, there's no getItem, there's only getAllItems).

Currently, my app goes to load the list, which causes the dataAccess module to make an ajax call to the API. Because it's asynchronous, the ajax response must drive the UI's next action. But the dataAccess module should not drive it directly, since it should know nothing about the UI. All it should know is who called it. So it simply calls a generic function (dataAccessReturn) in whatever called it.

So I've got this (note the dataAccess calling back to the UI):


UI:


loadList: function(){
..objCaller = this;
..DataAccess.getList(objCaller); // pass it myself so it can make a callback
},

dataAccessReturn: function(success,objListORErrCode){ // the callback
..if (success){
....populateUIwithobjList(objListORErrCode);
..}
..else{
....message(objListORErrCode)
..}
},



DataAccess:


getList: function(objCaller){
..Ext.Ajax.request({
....success: function(response, opts) {
......objCaller.dataAccessReturn(true,objList);
....}
....failure: function(response, opts) {
......objCaller.dataAccessReturn(false,errCode);
....}
..});
}


Fine so far. But now, rather than the UI being wired directly up to the database, I need an intermediary layer that holds the data objects. As mentioned, I will be wanting to get just a single item. That can't be done from the API directly. So I load the entire list into an object locally, and use it there. but I'm, still dependent on the Ajax responses to drive it all. so, my dataObjects methods become virtually pass-throughs.

Scary! A function in my dataObjects layer is both a caller and a callee at the same time.

UI:

loadList: function(){
..objCaller = this;
..DataObjects.getList(objCaller); // pass it myself so it can make a callback
},
dataObjectReturn: function(success,objList){ // the success callback
..if(success){
....populateUIwithobjList(objList);
..}
..else{
....message(errCode)
..}
},


DataObjects:

objTheList: {},
objCaller: null,

getList: function(objCaller){
..this.objCaller = objCaller;//store object that called me, so return can call it
..objTheList = DataAccess.getList(this); // pass it myself so it can make a callback
},

dataAccessReturn: function(success,objList){ // the callback
....this.objCaller.dataObjectReturn(success,objListORerrCode);
},



DataAccess:

getList: function(objCaller){
..Ext.Ajax.request({
....success: function(response, opts) {
......objCaller.dataAccessReturn(true,objList);
....}
....failure: function(response, opts) {
......objCaller.dataAccessReturn(false,errCode);
....}
..});
}


Note that not all DataObject methods are passthroughs. getItem operates on the list without having to go to the server:

DataObjects:

getItems: function(itemId){
..return objTheList.getItem(itemId);
},