Features in two-way binding.
What a magical function, which allows the change of view to be directly reflected in the data, and the change of data is notified to the view in real time. How to do it?
This is thanks to the following 3 important methods of scope:
$watch
$digest
$apply
What is their difference? Let's introduce:
$watch
This is a listener that listens to data on scope
Method Description:
$scope.$watch('parameter',function(newValue,oldValue){ //Logical processing})
Above we created a listener.
‘parameter’ is an object (or an object's property) under the $scope object. Note that this is a string form.
If you want to listen to the $ property.
$scope.$watch('name',function(newValue,oldValue){ //Logical processing})
As mentioned above, 'name' requires quotes
The parameter is followed by the callback function. The callback function parameter returns the listened attribute, the new value after the change, and the old value before the change.
$digest
He is responsible for checking whether the data in scope has changed. If a certain attribute changes, the listener of this attribute will be notified immediately (the listener registered by $watch), trigger the listener, and execute the callback function.
$apply
This method is very similar to $digest, which checks all data in scope
$apply is equivalent to checking all data in rootScope, it will check all data from parent to child
$apply() == $rootScope.$digest()
The $apply() method has two forms.
The first type accepts a function as a parameter.
This triggers the $digest function and executes the function in the parameter once
The second type does not accept any parameters.
This just triggers a $digest parent-child cycle
Class 1 will not call $digest directly, but will use $scope.$apply() instead.
I have not set up a monitor, why can views and data be bound in two-way
For example, a text box ng-model="name"
At this time, there is actually a property name under the $scope object to bind the two-way to the above view
How to achieve it?
In fact, when we define ng-model="name" or ng-bind="name" or {{name}}
At this time, a listener will be automatically set for the "name" property on the $scope model:
$scope.$watch('name', function(newValue, oldValue) { // Listen to the name attribute changes});
It turns out that we have automatically created a listener here, so this property and $ data will be bound in real time in two-way.
Of course, sometimes you will find that the data has changed. But the UI has not been refreshed. Is the two-way binding invalid?
No
It's just that when the $scope model traverses the digest loop, your data has not been returned yet.
For example, asynchronous call method, the data returned by callbac
For example, you set the timing trigger function in setTimeout and then modify the model data.
In short, the digest loop of the $scope model was missed, causing the model to notify the UI to refresh based on the new data.
What should I do if I encounter such a problem?
We had to manually call digest to check the data loop by ourselves. We realized two-way binding
As we have said above, usually, do not call the digest method directly, but call the $apply method manually to indirectly trigger the $digest loop.
as follows:
setTimeout(function() { $= 'A commoner'; $scope.$apply(); }, 2000);
The problem is here, you should call the apply method manually when the above
So far, the $apply() method has been automatically implemented for some directives and services.
For example, ng-click , ng-model , $timeout service , $http service , etc.
After calling, we will automatically call $apply() for us to realize two-way data binding.