Skip to content

Commit

Permalink
feat(ngModelOptions): Model update behavior can now be customized
Browse files Browse the repository at this point in the history
By default, any change on the content will trigger an immediate model update
and form validation. This PR implements a new directive `ng-model-options`
that allow you to override this default behavior in several ways.

You should specify an object with the different parameters.

For example, it allows to trigger an update only when a particular event or
list of events is received by the input using the `updateOn` key. Should you
need multiple events, just assign an array to it.

I.e. `ng-model-options="{ updateOn: 'blur' }"` will update and validate only
after the control loses focus.

If you want to keep the default behavior and just add new events that may
trigger the model update and validation, add "default" as one of the specified
events.

I.e. `ng-model-options="{ updateOn: ['default','submit'] }"`

Also, with the `debounce` option, `ng-model-options` will allow deferring the
actual model update until a timer expires. The timer will be reset each time
an event is triggered.

I.e. `ng-model-options="{ debounce: 500 }" for 500ms after the latest event.

Custom timeouts for each event can be set for each event if you use an object
in `debounce`. This can be useful to force immediate updates on some specific
circumstances (like blur events).

I.e. `ng-model-options="{ updateOn: ['default', 'blur'], debounce: { default: 500, blur: 0} }"`

You can use the directive in any tag so its contents became the default settings
for any child control, although they can be overridden.

Closes angular#1285, angular#2129
  • Loading branch information
lrlopez committed Apr 2, 2014
1 parent c704f76 commit c93c454
Show file tree
Hide file tree
Showing 3 changed files with 502 additions and 80 deletions.
77 changes: 77 additions & 0 deletions docs/content/guide/forms.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,83 @@ This allows us to extend the above example with these features:



# Custom triggers

By default, any change to the content will trigger a model update and form validation. You can
override this behavior using the {@link ng.directive:ngModelOptions ngModelOptions} directive to
bind only to specified list of events. I.e. `ng-model-options="{ updateOn: "blur" }"` will update
and validate only after the control loses focus. You can set a single event using an array instead
of a string. I.e. `ng-model-options="{ updateOn: ["mousedown", "blur"] }"`

If you want to keep the default behavior and just add new events that may trigger the model update
and validation, add "default" as one of the specified events.

I.e. `ng-model-options="{ updateOn: ["default", "blur"] }"`

The following example shows how to override immediate updates. Changes on the inputs within the form will update the model
only when the control loses focus (blur event).

<example>
<file name="index.html">
<div ng-controller="ControllerUpdateOn">
<form>
Name:
<input type="text" ng-model="user.name" ng-model-options="{ updateOn: "blur" }" /><br />
Other data:
<input type="text" ng-model="user.data" /><br />
</form>
<pre>username = "{{user.name}}"</pre>
</div>
</file>
<file name="script.js">
function ControllerUpdateOn($scope) {
$scope.user = {};
}
</file>
</example>



# Non-immediate (debounced) model updates

You can delay the model update/validation by using the `debounce` key with the
{@link ng.directive:ngModelOptions ngModelOptions} directive. This delay will also apply to
parsers, validators and model flags like `$dirty` or `$pristine`.


I.e. `ng-model-options="{ debounce: 500 }"` will wait for half a second since
the last content change before triggering the model update and form validation.

If custom triggers are used, custom debouncing timeouts can be set for each event using an object
in `debounce`. This can be useful to force immediate updates on some specific circumstances
(like blur events).

I.e. `ng-model-options="{ updateOn: ["default", "blur"], debounce: { default: 500, blur: 0 } }"`

If those attributes are added to an element, they will be applied to all the child elements and controls that inherit from it unless they are
overridden.

This example shows how to debounce model changes. Model will be updated only 250 milliseconds after last change.

<example>
<file name="index.html">
<div ng-controller="ControllerUpdateOn">
<form>
Name:
<input type="text" ng-model="user.name" ng-model-options="{ debounce: 250 }" /><br />
</form>
<pre>username = "{{user.name}}"</pre>
</div>
</file>
<file name="script.js">
function ControllerUpdateOn($scope) {
$scope.user = {};
}
</file>
</example>



# Custom Validation

Angular provides basic implementation for most common html5 {@link ng.directive:input input}
Expand Down
Loading

0 comments on commit c93c454

Please sign in to comment.