aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMisko Hevery2010-05-07 12:09:14 -0700
committerMisko Hevery2010-05-07 12:09:14 -0700
commit038a743e6f49c347a38edc0e54dcbb175905a475 (patch)
tree8eb10232c94967159175bde5a9209aaf5ba07c67 /src
parentac1d02d0658cb74ae3822e364f84809d78cda335 (diff)
downloadangular.js-038a743e6f49c347a38edc0e54dcbb175905a475.tar.bz2
xhr bulk fixes
Diffstat (limited to 'src')
-rw-r--r--src/Angular.js19
-rw-r--r--src/AngularPublic.js1
-rw-r--r--src/Browser.js3
-rw-r--r--src/JSON.js2
-rw-r--r--src/Resource.js12
-rw-r--r--src/Scope.js4
-rw-r--r--src/services.js71
7 files changed, 74 insertions, 38 deletions
diff --git a/src/Angular.js b/src/Angular.js
index 3af21ced..2df6bbef 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -231,13 +231,14 @@ function isLeafNode (node) {
function copy(source, destination){
if (!destination) {
- if (isArray(source)) {
- return copy(source, []);
- } else if (isObject(source)) {
- return copy(source, {});
- } else {
- return source;
+ if (source) {
+ if (isArray(source)) {
+ return copy(source, []);
+ } else if (isObject(source)) {
+ return copy(source, {});
+ }
}
+ return source;
} else {
if (isArray(source)) {
while(destination.length) {
@@ -249,7 +250,11 @@ function copy(source, destination){
});
}
foreach(source, function(value, key){
- destination[key] = isArray(value) ? copy(value, []) : (isObject(value) ? copy(value, {}) : value);
+ destination[key] = value ?
+ ( isArray(value) ?
+ copy(value, []) :
+ (isObject(value) ? copy(value, {}) : value)) :
+ value;
});
return destination;
}
diff --git a/src/AngularPublic.js b/src/AngularPublic.js
index 1739ac4b..7230c3e5 100644
--- a/src/AngularPublic.js
+++ b/src/AngularPublic.js
@@ -22,6 +22,7 @@ extend(angular, {
'isDefined': isDefined,
'isString': isString,
'isFunction': isFunction,
+ 'isObject': isObject,
'isNumber': isNumber,
'isArray': isArray
});
diff --git a/src/Browser.js b/src/Browser.js
index 6ec083fa..2a90b63f 100644
--- a/src/Browser.js
+++ b/src/Browser.js
@@ -8,6 +8,7 @@ function Browser(location, document) {
this.expectedUrl = location.href;
this.urlListeners = [];
this.hoverListener = noop;
+ this.isMock = false;
this.XHR = window.XMLHttpRequest || function () {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
@@ -64,7 +65,7 @@ Browser.prototype = {
callback(xhr.status || 200, xhr.responseText);
}
};
- xhr.send('');
+ xhr.send(post || '');
},
watchUrl: function(fn){
diff --git a/src/JSON.js b/src/JSON.js
index 5c3e1043..340b075a 100644
--- a/src/JSON.js
+++ b/src/JSON.js
@@ -74,7 +74,7 @@ function toJsonArray(buf, obj, pretty, stack){
var childPretty = pretty ? pretty + " " : false;
var keys = [];
for(var k in obj) {
- if (k.indexOf('$$') === 0)
+ if (k.indexOf('$$') === 0 || obj[k] === undefined)
continue;
keys.push(k);
}
diff --git a/src/Resource.js b/src/Resource.js
index 34ad1c5d..c9bad0c0 100644
--- a/src/Resource.js
+++ b/src/Resource.js
@@ -21,7 +21,7 @@ Route.prototype = {
});
url = url.replace(/\/?#$/, '');
var query = [];
- foreach(params, function(value, key){
+ foreachSorted(params, function(value, key){
if (!self.urlParams[key]) {
query.push(encodeURI(key) + '=' + encodeURI(value));
}
@@ -69,14 +69,18 @@ ResourceFactory.prototype = {
switch(arguments.length) {
case 3: callback = a3;
case 2:
- if (typeof a2 == 'function') {
+ if (isFunction(a2)) {
callback = a2;
} else {
params = a1;
data = a2;
break;
}
- case 1: if (isPost) data = a1; else params = a1; break;
+ case 1:
+ if (isFunction(a1)) callback = a1;
+ else if (isPost) data = a1;
+ else params = a1;
+ break;
case 0: break;
default:
throw "Expected between 0-3 arguments [params, data, callback], got " + arguments.length + " arguments.";
@@ -109,7 +113,7 @@ ResourceFactory.prototype = {
case 1: if (typeof a1 == 'function') callback = a1; else params = a1;
case 0: break;
default:
- throw "Expected between 1-3 arguments [params, data, callback], got " + arguments.length + " arguments.";
+ throw "Expected between 1-2 arguments [params, callback], got " + arguments.length + " arguments.";
}
var self = this;
Resource[name](params, this, function(response){
diff --git a/src/Scope.js b/src/Scope.js
index 1b93418f..9a20c214 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -97,7 +97,7 @@ function createScope(parent, services, existing) {
$set: bind(instance, setter, instance),
$eval: function $eval(exp) {
- if (isDefined(exp)) {
+ if (exp) {
return expressionCompile(exp).apply(instance, slice.call(arguments, 1, arguments.length));
} else {
foreach(evalLists.sorted, function(list) {
@@ -129,8 +129,8 @@ function createScope(parent, services, existing) {
function watcher(){
var value = watch.call(instance);
if (last !== value) {
- instance.$tryEval(listener, exceptionHandler, value, last);
last = value;
+ instance.$tryEval(listener, exceptionHandler, value, last);
}
}
instance.$onEval(PRIORITY_WATCH, watcher);
diff --git a/src/services.js b/src/services.js
index 2cf0e4ad..195cd6b3 100644
--- a/src/services.js
+++ b/src/services.js
@@ -64,6 +64,12 @@ angularService("$location", function(browser){
return location;
}, {inject: ['$browser']});
+angularService("$log", function(){
+ return {
+ error: noop
+ };
+});
+
angularService("$hover", function(browser) {
var tooltip, self = this, error, width = 300, arrowWidth = 10;
browser.hover(function(element, show){
@@ -152,6 +158,7 @@ angularService('$route', function(location, params){
onChange = [],
matcher = angularWidget('NG:SWITCH').route,
parentScope = this,
+ dirty = 0,
$route = {
routes: routes,
onChange: bind(onChange, onChange.push),
@@ -160,7 +167,7 @@ angularService('$route', function(location, params){
var route = routes[path];
if (!route) route = routes[path] = {};
if (params) angular.extend(route, params);
- if (matcher(location.hashPath, path)) updateRoute();
+ dirty++;
return route;
}
};
@@ -185,7 +192,7 @@ angularService('$route', function(location, params){
parentScope.$tryEval(childScope.init);
}
}
- this.$watch(function(){return location.hash;}, updateRoute);
+ this.$watch(function(){return dirty + location.hash;}, updateRoute);
return $route;
}, {inject: ['$location']});
@@ -221,32 +228,49 @@ angularService('$xhr.bulk', function($xhr){
callback = post;
post = null;
}
- requests.push({method: method, url: url, data:post});
- callbacks.push(callback);
+ var currentQueue;
+ foreach(bulkXHR.urls, function(queue){
+ if (isFunction(queue.match) ? queue.match(url) : queue.match.exec(url)) {
+ currentQueue = queue;
+ }
+ });
+ if (currentQueue) {
+ if (!currentQueue.requests) currentQueue.requests = [];
+ if (!currentQueue.callbacks) currentQueue.callbacks = [];
+ currentQueue.requests.push({method: method, url: url, data:post});
+ currentQueue.callbacks.push(callback);
+ } else {
+ $xhr(method, url, post, callback);
+ }
}
- bulkXHR.url = "/bulk";
+ bulkXHR.urls = {};
bulkXHR.flush = function(callback){
- var currentRequests = requests,
- currentCallbacks = callbacks;
- requests = [];
- callbacks = [];
- $xhr('POST', bulkXHR.url, {requests:currentRequests}, function(code, response){
- foreach(response, function(response, i){
- try {
- (currentCallbacks[i] || noop)(response.status, response.response);
- } catch(e) {
- self.$log.error(e);
- }
- });
- (callback || noop)();
+ foreach(bulkXHR.urls, function(queue, url){
+ var currentRequests = queue.requests,
+ currentCallbacks = queue.callbacks;
+ if (currentRequests && currentRequests.length) {
+ queue.requests = [];
+ queue.callbacks = [];
+ $xhr('POST', url, {requests:currentRequests}, function(code, response){
+ foreach(response, function(response, i){
+ try {
+ (currentCallbacks[i] || noop)(response.status, response.response);
+ } catch(e) {
+ scope.$log.error(e);
+ }
+ });
+ (callback || noop)();
+ });
+ scope.$eval();
+ }
});
- scope.$eval();
};
+ this.$onEval(PRIORITY_LAST, bulkXHR.flush);
return bulkXHR;
}, {inject:['$xhr']});
angularService('$xhr.cache', function($xhr){
- var inflight = {};
+ var inflight = {}, self = this;;
function cache(method, url, post, callback){
if (isFunction(post)) {
callback = post;
@@ -263,14 +287,15 @@ angularService('$xhr.cache', function($xhr){
cache.delegate(method, url, post, function(status, response){
if (status == 200)
cache.data[url] = { value: response };
- foreach(inflight[url].callbacks, function(callback){
+ var callbacks = inflight[url].callbacks;
+ delete inflight[url];
+ foreach(callbacks, function(callback){
try {
(callback||noop)(status, copy(response));
} catch(e) {
self.$log.error(e);
}
});
- delete inflight[url];
});
}
} else {
@@ -281,7 +306,7 @@ angularService('$xhr.cache', function($xhr){
cache.data = {};
cache.delegate = $xhr;
return cache;
-}, {inject:['$xhr']});
+}, {inject:['$xhr.bulk']});
angularService('$resource', function($xhr){
var resource = new ResourceFactory($xhr);