What's the difference between ng-model and ng-bind
I'm currently learning AngularJS and am having difficulty understanding the difference between ng-bind
and ng-model
.
Can anyone tell me how they differ and when one should be used over the other?
Solution 1:
ng-bind has one-way data binding ($scope --> view). It has a shortcut {{ val }}
which displays the scope value $scope.val
inserted into html where val
is a variable name.
ng-model is intended to be put inside of form elements and has two-way data binding ($scope --> view and view --> $scope) e.g. <input ng-model="val"/>
.
Solution 2:
tosh's answer gets to the heart of the question nicely. Here's some additional information....
Filters & Formatters
ng-bind
and ng-model
both have the concept of transforming data before outputting it for the user. To that end, ng-bind
uses filters, while ng-model
uses formatters.
filter (ng-bind)
With ng-bind
, you can use a filter to transform your data. For example,
<div ng-bind="mystring | uppercase"></div>
,
or more simply:
<div>{{mystring | uppercase}}</div>
Note that uppercase
is a built-in angular filter, although you can also build your own filter.
formatter (ng-model)
To create an ng-model formatter, you create a directive that does require: 'ngModel'
, which allows that directive to gain access to ngModel's controller
. For example:
app.directive('myModelFormatter', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, controller) {
controller.$formatters.push(function(value) {
return value.toUpperCase();
});
}
}
}
Then in your partial:
<input ngModel="mystring" my-model-formatter />
This is essentially the ng-model
equivalent of what the uppercase
filter is doing in the ng-bind
example above.
Parsers
Now, what if you plan to allow the user to change the value of mystring
? ng-bind
only has one way binding, from model-->view. However, ng-model
can bind from view-->model which means that you may allow the user to change the model's data, and using a parser you can format the user's data in a streamlined manner. Here's what that looks like:
app.directive('myModelFormatter', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, controller) {
controller.$parsers.push(function(value) {
return value.toLowerCase();
});
}
}
}
Play with a live plunker of the ng-model
formatter/parser examples
What Else?
ng-model
also has built-in validation. Simply modify your $parsers
or $formatters
function to call ngModel's controller.$setValidity(validationErrorKey, isValid)
function.
Angular 1.3 has a new $validators array which you can use for validation instead of $parsers
or $formatters
.
Angular 1.3 also has getter/setter support for ngModel
Solution 3:
ngModel
The ngModel directive binds an input,select, textarea (or custom form control) to a property on the scope.This directive executes at priority level 1.
Example Plunker
JAVASCRIPT
angular.module('inputExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.val = '1';
}]);
CSS
.my-input {
-webkit-transition:all linear 0.5s;
transition:all linear 0.5s;
background: transparent;
}
.my-input.ng-invalid {
color:white;
background: red;
}
HTML
<p id="inputDescription">
Update input to see transitions when valid/invalid.
Integer is a valid value.
</p>
<form name="testForm" ng-controller="ExampleController">
<input ng-model="val" ng-pattern="/^\d+$/" name="anim" class="my-input"
aria-describedby="inputDescription" />
</form>
ngModel is responsible for:
- Binding the view into the model, which other directives such as input, textarea or select require.
- Providing validation behavior (i.e. required, number, email, url).
- Keeping the state of the control (valid/invalid, dirty/pristine, touched/untouched, validation errors).
- Setting related css classes on the element (ng-valid, ng-invalid, ng-dirty, ng-pristine, ng-touched, ng-untouched) including animations.
- Registering the control with its parent form.
ngBind
The ngBind attribute tells Angular to replace the text content of the specified HTML element with the value of a given expression, and to update the text content when the value of that expression changes.This directive executes at priority level 0.
Example Plunker
JAVASCRIPT
angular.module('bindExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.name = 'Whirled';
}]);
HTML
<div ng-controller="ExampleController">
<label>Enter name: <input type="text" ng-model="name"></label><br>
Hello <span ng-bind="name"></span>!
</div>
ngBind is responsible for:
- Replacing the text content of the specified HTML element with the value of a given expression.
Solution 4:
If you are hesitating between using ng-bind
or ng-model
, try to answer these questions:
Do you only need to display data?
Yes:
ng-bind
(one-way binding)No:
ng-model
(two-way binding)
Do you need to bind text content (and not value)?
Yes:
ng-bind
No:
ng-model
(you should not use ng-bind where value is required)
Is your tag a HTML
<input>
?
Yes:
ng-model
(you cannot use ng-bind with<input>
tag)No:
ng-bind