Sending a response object along to the user callback after a commit that issues multiple requests. Thanks for the collaborative patch work crschmidt. r=crschmidt,elemoine (closes #1973)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@9246 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
Tim Schaub
2009-04-08 17:52:55 +00:00
parent 861a9c10f5
commit 0e858fa4af
2 changed files with 76 additions and 105 deletions
+32 -12
View File
@@ -412,12 +412,13 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
types[OpenLayers.State.INSERT] = []; types[OpenLayers.State.INSERT] = [];
types[OpenLayers.State.UPDATE] = []; types[OpenLayers.State.UPDATE] = [];
types[OpenLayers.State.DELETE] = []; types[OpenLayers.State.DELETE] = [];
var feature, list; var feature, list, requestFeatures = [];
for(var i=0, len=features.length; i<len; ++i) { for(var i=0, len=features.length; i<len; ++i) {
feature = features[i]; feature = features[i];
list = types[feature.state]; list = types[feature.state];
if(list) { if(list) {
list.push(feature); list.push(feature);
requestFeatures.push(feature);
} }
} }
// tally up number of requests // tally up number of requests
@@ -425,10 +426,35 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
types[OpenLayers.State.UPDATE].length + types[OpenLayers.State.UPDATE].length +
types[OpenLayers.State.DELETE].length; types[OpenLayers.State.DELETE].length;
// This response will be sent to the final callback after all the others
// have been fired.
var success = true;
var finalResponse = new OpenLayers.Protocol.Response({
reqFeatures: requestFeatures
});
function insertCallback(response) {
var len = response.features ? response.features.length : 0;
var fids = new Array(len);
for(var i=0; i<len; ++i) {
fids[i] = response.features[i].fid;
}
finalResponse.insertIds = fids;
callback.apply(this, [response]);
}
function callback(response) { function callback(response) {
nResponses++;
response.last = (nResponses >= nRequests);
this.callUserCallback(response, options); this.callUserCallback(response, options);
success = success && response.success();
nResponses++;
if (nResponses >= nRequests) {
if (options.callback) {
finalResponse.code = success ?
OpenLayers.Protocol.Response.SUCCESS :
OpenLayers.Protocol.Response.FAILURE;
options.callback.apply(options.scope, [finalResponse]);
}
}
} }
// start issuing requests // start issuing requests
@@ -436,8 +462,7 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
if(queue.length > 0) { if(queue.length > 0) {
resp.push(this.create( resp.push(this.create(
queue, OpenLayers.Util.applyDefaults( queue, OpenLayers.Util.applyDefaults(
{callback: callback, scope: this}, {callback: insertCallback, scope: this}, options.create
options.create || {} // remove || when #1716 is resolved
) )
)); ));
} }
@@ -445,8 +470,7 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
for(var i=queue.length-1; i>=0; --i) { for(var i=queue.length-1; i>=0; --i) {
resp.push(this.update( resp.push(this.update(
queue[i], OpenLayers.Util.applyDefaults( queue[i], OpenLayers.Util.applyDefaults(
{callback: callback, scope: this}, {callback: callback, scope: this}, options.update
options.update || {} // remove || when #1716 is resolved
)) ))
); );
} }
@@ -454,8 +478,7 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
for(var i=queue.length-1; i>=0; --i) { for(var i=queue.length-1; i>=0; --i) {
resp.push(this["delete"]( resp.push(this["delete"](
queue[i], OpenLayers.Util.applyDefaults( queue[i], OpenLayers.Util.applyDefaults(
{callback: callback, scope: this}, {callback: callback, scope: this}, options["delete"]
options["delete"] || {} // remove || when #1716 is resolved
)) ))
); );
} }
@@ -492,9 +515,6 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
if(opt && opt.callback) { if(opt && opt.callback) {
opt.callback.call(opt.scope, resp); opt.callback.call(opt.scope, resp);
} }
if(resp.last && options.callback) {
options.callback.call(options.scope);
}
}, },
CLASS_NAME: "OpenLayers.Protocol.HTTP" CLASS_NAME: "OpenLayers.Protocol.HTTP"
+40 -89
View File
@@ -659,132 +659,83 @@
} }
function test_callUserCallback(t) { function test_callUserCallback(t) {
t.plan(6); t.plan(1);
var protocol = new OpenLayers.Protocol.HTTP(); var protocol = new OpenLayers.Protocol.HTTP();
var options, resp;
var scope = {'fake': 'scope'}; var scope = {'fake': 'scope'};
// test commit callback // test commit callback
// 1 tests var log = {};
options = { var options = {
'callback': function() { foo: {
t.ok(this == scope, 'callback called with correct scope'); callback: function() {
}, log.scope = this;
'scope': scope
};
resp = {'requestType': 'create', 'last': true};
protocol.callUserCallback(resp, options);
// 0 test
resp = {'requestType': 'create', 'last': false};
protocol.callUserCallback(resp, options);
// test create callback
// 2 tests
options = {
'create': {
'callback': function(r) {
t.ok(this == scope, 'callback called with correct scope');
t.ok(r == resp, 'callback called with correct response');
}, },
'scope': scope scope: scope
} }
}; };
resp = {'requestType': 'create'}; var resp = {requestType: 'foo'};
protocol.callUserCallback(resp, options); protocol.callUserCallback(resp, options);
t.ok(log.scope, scope, 'correct callback called with correct scope');
// test with both callbacks set
// 3 tests
options = {
'create': {
'callback': function(r) {
t.ok(this == scope, 'callback called with correct scope');
t.ok(r == resp, 'callback called with correct response');
},
'scope': scope
},
'callback': function() {
t.ok(this == scope, 'callback called with correct scope');
},
'scope': scope
};
resp = {'requestType': 'create', 'last': true};
protocol.callUserCallback(resp, options);
// no callback set
// 0 test
options = {
'delete': {
'callback': function(resp) {
t.fail('callback should not get called');
}
}
};
resp = {'requestType': 'create'};
protocol.callUserCallback(resp, options);
// cleanup
protocol.destroy();
} }
function test_options(t) { function test_options(t) {
t.plan(7); t.plan(6);
var _R = OpenLayers.Protocol.Response; var log1 = {};
OpenLayers.Protocol.Response = function() {
this.priv = {status: 200};
};
// test that read with no options uses protocol options - 5 tests // test that read with no options uses protocol options - 5 tests
var url = "foo"; var url = ".";
var headers = {}; var headers = {};
var params = {}; var params = {};
var scope = {}; var scope = {};
var protocol = new OpenLayers.Protocol.HTTP({ var protocol = new OpenLayers.Protocol.HTTP({
format: new OpenLayers.Format({read: function(){}, write: function(){}}), format: new OpenLayers.Format({
read: function() {},
write: function() {}
}),
url: url, url: url,
headers: headers, headers: headers,
params: params, params: params,
callback: function() { callback: function(resp) {
t.ok(true, "[read] Correct callback."); log1.callbackCalled = true;
t.eq(this, scope, "[read] Correct scope."); log1.callbackScope = this;
log1.request = resp && resp.priv;
log1.requestType = resp && resp.requestType;
}, },
scope: scope scope: scope
}); });
var _issue = OpenLayers.Request.issue;
OpenLayers.Request.issue = function(config) {
t.eq(config.url, url, "[" + config.method + "] Correct url.");
t.eq(config.headers, headers, "[" + config.method + "] Correct headers.");
t.eq(config.params, params, "[" + config.method + "] Correct params.");
config.callback.call(config.scope);
};
protocol.read(); protocol.read();
OpenLayers.Request.issue = _issue;
t.delay_call(0.5, function() {
t.eq(log1.callbackCalled, true, "[read] callback called");
t.eq(log1.callbackScope, scope, "[read] correct scope");
t.ok(log1.request instanceof OpenLayers.Request.XMLHttpRequest, "[read] correct priv type");
t.eq(log1.requestType, "read", "[read] correct request type");
});
// test that commit with no options uses protocol options - 2 tests // test that commit with no options uses protocol options - 2 tests
_issue = OpenLayers.Request.issue; var log2 = {called: 0};
OpenLayers.Request.issue = function(config) {
config.callback.call(config.scope);
};
var called = 0;
protocol.options.callback = function() { protocol.options.callback = function() {
called++; log2.called++;
t.eq(this, scope, "[commit] Correct scope."); log2.scope = this;
}; };
protocol.commit([ protocol.commit([
{state: OpenLayers.State.INSERT}, {state: OpenLayers.State.INSERT},
{state: OpenLayers.State.INSERT}, {state: OpenLayers.State.INSERT},
{state: OpenLayers.State.UPDATE}, {state: OpenLayers.State.UPDATE, url: "./1"},
{state: OpenLayers.State.UPDATE}, {state: OpenLayers.State.UPDATE, url: "./2"},
{state: OpenLayers.State.DELETE}, {state: OpenLayers.State.DELETE, url: "./3"},
{state: OpenLayers.State.DELETE} {state: OpenLayers.State.DELETE, url: "./4"}
]); ]);
t.eq(called, 1, "[commit] Callback called once."); t.delay_call(0.5, function() {
t.eq(log2.called, 1, "[commit] Callback called once.");
t.eq(log2.scope, scope, "[commit] Correct scope.");
});
// cleanup
protocol.destroy();
OpenLayers.Protocol.Response = _R;
} }