Objective
In angular applications, an integral part of the ng-model instruction, which is used to bind the view to data, is an important link in the bidirectional binding magic. Ngmodelcontroller is the controller defined in the Ng-model directive. This controller contains a number of services for data binding, validation, CSS updates, and numeric formatting and parsing. It is not used for DOM rendering or for listening to DOM events. DOM-related logic should be included in other directives, and then let these instructions try to test the data binding functionality in Ngmodelcontroller.
Note : This article is not a description of the Ngmodelcontroller document, but rather a more biased practice. I'm going to lead you through a custom directive, and use the Ng-model attribute to do both data binding.
Example
We use a custom directive in our app named Timedruation.
As follows
<div ng-app= "HelloApp" ng-controller= "Hellocontroller" >
The JS code is as follows,
Angular.module (' HelloApp ', [])
. Directive (' timeduration ', timedurationdirective);
Controller (' Hellocontroller ', function ($scope) {
$scope. test = 1;
});
Our example directive can do this by specifying several common time units and being able to enter data. Eventually we'll get the corresponding number of seconds. The screenshot of its function is as follows,
Here we specifically bind the test variables to our custom directives and the default directives to observe their effects.
Custom directives
Gossip less, look at the code below
The template for the first instruction. As you can see from the illustration above, the instruction contains an input box and a drop-down selection box.
<div class= "Time-duration" >
<input ng-model= ' num ' >
<select ng-model= ' unit ' >
< Option value= "Seconds" >Seconds</option>
<option value= "Minutes" >Minutes</option>
<option value= "Hours" >Hours</option>
<option value= "Days" >Days</option>
</ Select>
</div>
The template is actually very simple, there is no more to say. Now let's take a look at the logical part of this instruction.
function timedurationdirective () {
var tpl = ' ... ';//directive template code is the content above, it is not copied here. Return
{
restrict: ' E ',
replace:true,
template:tpl,
require: ' Ngmodel ',
scope: {},
Link:function (scope, element, Attrs, Ngmodelcontroller) {
var multipliermap = {
seconds:1,
minutes:60,< c12/>hours:3600,
days:86400
};
var multipliertypes = [' seconds ', ' minutes ', ' hours ', ' days '];
TODO
}
};
}
The link method of the instruction we've been todo it for a while. The latter will gradually improve.
Let me take a look at the definition of this directive, which uses the require declaration. In simple terms, the role of require is to declare a dependency for this directive, indicating that this directive relies on the controller attribute of another instruction.
Here's a little bit of a require derivative usage.
We can add rhetorical quantifiers before require, for example,
return {
require: ' ^ngmodel '
} return
{
require: '? Ngmodel '
} return
{
require: ' ? ^ngmodel '
}
1. ^ prefix decoration indicates that the parent directive is allowed to find the current instruction, and an error is thrown if the controller of the corresponding instruction is not found.
2,? It means that the require action into an optional, meaning that the corresponding instructions can not find the controller even if it does not throw errors.
3. Of course, we can also use these two prefixes to modify together.
Ngmodel,^ngmodel we use a higher frequency.
Like what
<my-directive ng-model= "My-model" >
<other-directive></other-directive>
</ My-directive>
At this point, we use it in Other-directiverequire: ^ngModel, which will automatically find the controller attribute in the my-directive instruction declaration.
Using Ngmodelcontroller
When we declare itrequire: 'ngModel', the fourth parameter is injected into the link method, which is the corresponding controller of the instruction we require. Here is the built-in command Ngmodel's Ngmodecontroller.
Link:function (scope, element, Attrs, Ngmodelctrl) {
//TODO
}
$viewValue and $modelvalue
There are two very important attributes in Ngmodelcontroller, one called $viewvalue and one called $modevalue.
The official explanation of the two meanings is as follows
$viewValue: Actual string value in the view.
$modelValue: The value in the model, which is bound to.
If you have any doubts about the official explanations above, I give a personal explanation here.
$viewView is the value that the instruction uses to render the template, and $modelview is the value that is circulated in the controller. Most of the time, these two values may not be the same.
For example, you show a date on the page that might display a string such as "Oct. 20 2015", but the corresponding value of this string in the controller might be an instance of a JavaScript date object.
For example, in our time-duration example, $viewValue actually refers to the values that are combined with NUM and unit in the instruction template, and $modelvalue is the value of the test variable in Helloappcontroller.
$formatters and $parses
In addition to the two properties of $viewvalue and $modelvalue, there are two ways to handle them. respectively, $parses and $formatters.
The former's role is to be$viewValue->$modelValue, the latter role is exactly the opposite, is to be$modelValue->$viewValue.
The time-duration instruction and external controller as well as its internal operation are shown below,
1, in the external controller (that is, the HelloApp of the controller), we pass theng-model="test"test variable into the instruction time-duration and establish the binding relationship.
2. Inside the instruction, $modelValue is actually a copy of the test value.
3, we$formatters()change the $modelvalue into $viewvalue by means of the method.
4, then invoke the$render()method to render the $viewvalue to the directive template.
5, we call to update $viewvalue when we monitor the variable in the instruction template in some way$setViewValue().
6, and (4) corresponding, we through $parsers method to convert $viewvalue into $modelvalue.
7, when the $modelvalue changes, it will update the HelloApp UI.
Perfecting instruction Logic
According to the above procedure, we first convert the $modelvalue to $viewvalue and then render it in the instruction template.
$formatters accept an array
//array is a series of methods used to convert Modelvalue into Viewvalue
ngmodelcontroller. $formatters. Push (Function ( Modelvalue) {
var unit = ' minutes ', num = 0, I, unitname;
Modelvalue = parseint (Modelvalue | | 0);
for (i = multipliertypes.length-1 i >= 0; i--) {
unitname = multipliertypes[i];
if (modelvalue% multipliermap[unitname] = = 0) {Unit
= unitname;
break;
}
}
if (modelvalue) {
num = Modelvalue/multipliermap[unit];
}
return {
unit:unit,
num:num
};
};
The last object returned is the value of $viewvalue. (Of course $viewvalue will have some other attributes, too.) )
In the second step, we call the $render method to render the $viewvalue to the instruction template.
The $render is used to render viewvalue to the ngmodelcontroller of the instruction
. $render = function () {
scope.unit = ngmodelctrl.$ Viewvalue.unit;
Scope.num = Ngmodelctrl. $viewValue. Num
};
In the third step, we monitor the NUM and unit variables in the instruction template by $watch. When it changes, we need to update the $viewvalue.
Scope. $watch (' unit + num ', function () {
//$setViewValue is used to update Viewvalue
Ngmodelcontroller. $setViewValue ({
unit:scope.unit,
num:scope.num
});
In the fourth step, we will $viewvalue-> $modelValue through $parsers.
$parsers accept an array
//array is a series of methods used to convert Viewvalue into Modelvalue
ngmodelcontroller. $parsers. Push (Function ( Viewvalue) {
var unit = viewvalue.unit;
var num = viewvalue.num;
var multiplier;
multiplier = Multipliermap[unit];
return num * multiplier;
});
Summarize
Well, the data binding logic on both sides is established. I wonder if everyone has learned it? I hope the content of this article for everyone's study or work can bring certain help, if there is doubt you can message exchange.