aboutsummaryrefslogtreecommitdiffstats
path: root/src/services.js
diff options
context:
space:
mode:
authorMisko Hevery2010-12-10 13:55:18 -0800
committerIgor Minar2011-01-07 14:39:46 -0800
commit47c454a315b6c0260c8f65e70ae9b30f924650df (patch)
tree3392daf6242d540a6f3d7bb08ef4914aa46c667e /src/services.js
parent16086aa37c5c0c98f5c4a42d2a15136bb6d18605 (diff)
downloadangular.js-47c454a315b6c0260c8f65e70ae9b30f924650df.tar.bz2
change to keydown from keyup; add delayed $updateView
- There was a perceived lag when typing do to the fact that we were listening on the keyup event instead of keydown. The issue with keydown is that we can not read the value of the input field. To solve this we schedule a defer call and perform the model update then. - To prevent calling $eval on root scope too many times as well as to prevent drowning the browser with too many updates we now call the $eval only after 25ms and any additional requests get ignored. The new update service is called $updateView
Diffstat (limited to 'src/services.js')
-rw-r--r--src/services.js62
1 files changed, 59 insertions, 3 deletions
diff --git a/src/services.js b/src/services.js
index 91bd226d..1a2aada6 100644
--- a/src/services.js
+++ b/src/services.js
@@ -408,6 +408,62 @@ angularServiceInject('$exceptionHandler', function($log){
/**
* @workInProgress
* @ngdoc service
+ * @name angular.service.$updateView
+ * @requires $browser
+ *
+ * @description
+ * Calling `$updateView` enqueues the eventual update of the view. (Update the DOM to reflect the
+ * model). The update is eventual, since there are often multiple updates to the model which may
+ * be deferred. The default update delayed is 25 ms. This means that the view lags the model by
+ * that time. (25ms is small enough that it is perceived as instantaneous by the user). The delay
+ * can be adjusted by setting the delay property of the service.
+ *
+ * <pre>angular.service('$updateView').delay = 10</pre>
+ *
+ * The delay is there so that multiple updates to the model which occur sufficiently close
+ * together can be merged into a single update.
+ *
+ * You don't usually call '$updateView' directly since angular does it for you in most cases,
+ * but there are some cases when you need to call it.
+ *
+ * - `$updateView()` called automatically by angular:
+ * - Your Application Controllers: Your controller code is called by angular and hence
+ * angular is aware that you may have changed the model.
+ * - Your Services: Your service is usually called by your controller code, hence same rules
+ * apply.
+ * - May need to call `$updateView()` manually:
+ * - Widgets / Directives: If you listen to any DOM events or events on any third party
+ * libraries, then angular is not aware that you may have changed state state of the
+ * model, and hence you need to call '$updateView()' manually.
+ * - 'setTimeout'/'XHR': If you call 'setTimeout' (instead of {@link angular.service.$defer})
+ * or 'XHR' (instead of {@link angular.service.$xhr}) then you may be changing the model
+ * without angular knowledge and you may need to call '$updateView()' directly.
+ *
+ * NOTE: if you wish to update the view immediately (without delay), you can do so by calling
+ * {@link scope.$eval} at any time from your code:
+ * <pre>scope.$root.$eval()</pre>
+ *
+ * In unit-test mode the update is instantaneous and synchronous to simplify writing tests.
+ *
+ */
+angularServiceInject('$updateView', extend(function factory($browser){
+ var rootScope = this;
+ var scheduled;
+ function update(){
+ scheduled = false;
+ rootScope.$eval();
+ }
+ return $browser.isMock ? update : function(){
+ if (!scheduled) {
+ scheduled = true;
+ $browser.defer(update, factory.delay);
+ }
+ };
+}, {delay:25}), ['$browser']);
+
+/**
+ * @workInProgress
+ * @ngdoc service
* @name angular.service.$hover
* @requires $browser
* @requires $document
@@ -815,7 +871,7 @@ angularServiceInject('$xhr.bulk', function($xhr, $error, $log){
*
* @param {function()} fn A function, who's execution should be deferred.
*/
-angularServiceInject('$defer', function($browser, $exceptionHandler) {
+angularServiceInject('$defer', function($browser, $exceptionHandler, $updateView) {
var scope = this;
return function(fn) {
@@ -825,11 +881,11 @@ angularServiceInject('$defer', function($browser, $exceptionHandler) {
} catch(e) {
$exceptionHandler(e);
} finally {
- scope.$eval();
+ $updateView();
}
});
};
-}, ['$browser', '$exceptionHandler']);
+}, ['$browser', '$exceptionHandler', '$updateView']);
/**