From 47c454a315b6c0260c8f65e70ae9b30f924650df Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Fri, 10 Dec 2010 13:55:18 -0800 Subject: 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 --- src/widgets.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/widgets.js') diff --git a/src/widgets.js b/src/widgets.js index 05979281..5ff4a28f 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -376,7 +376,7 @@ function optionsAccessor(scope, element) { function noopAccessor() { return { get: noop, set: noop }; } -var textWidget = inputWidget('keyup change', modelAccessor, valueAccessor, initWidgetValue(), true), +var textWidget = inputWidget('keydown change', modelAccessor, valueAccessor, initWidgetValue(), true), buttonWidget = inputWidget('click', noopAccessor, noopAccessor, noop), INPUT_TYPE = { 'text': textWidget, @@ -454,8 +454,8 @@ function radioInit(model, view, element) { expect(binding('checkboxCount')).toBe('1'); }); */ -function inputWidget(events, modelAccessor, viewAccessor, initFn, dirtyChecking) { - return function(element) { +function inputWidget(events, modelAccessor, viewAccessor, initFn, textBox) { + return injectService(['$updateView', '$defer'], function($updateView, $defer, element) { var scope = this, model = modelAccessor(scope, element), view = viewAccessor(scope, element), @@ -464,25 +464,25 @@ function inputWidget(events, modelAccessor, viewAccessor, initFn, dirtyChecking) if (model) { initFn.call(scope, model, view, element); this.$eval(element.attr('ng:init')||''); - // Don't register a handler if we are a button (noopAccessor) and there is no action - if (action || modelAccessor !== noopAccessor) { - element.bind(events, function (){ + element.bind(events, function(event){ + function handler(){ var value = view.get(); - if (!dirtyChecking || value != lastValue) { + if (!textBox || value != lastValue) { model.set(value); lastValue = model.get(); scope.$tryEval(action, element); - scope.$root.$eval(); + $updateView(); } - }); - } + } + event.type == 'keydown' ? $defer(handler) : handler(); + }); scope.$watch(model.get, function(value){ if (lastValue !== value) { view.set(lastValue = value); } }); } - }; + }); } function inputWidgetSelector(element){ -- cgit v1.2.3