About how to implement bidirectional binding in angular. js $ watch $ digest $ apply, angular. jsdigest
Angular. js features, two-way binding.
What a magical function is to make changes to the view directly reflect the changes to the data, and the changes to the data are notified to the view in real time. How can this be done?
This is due to the following three important methods in scope:
$ Watch
$ Digest
$ Apply
What are their differences? Let's introduce them:
$ Watch
This is a listener that listens to data on the scope.
Method description:
$ Scope. $ watch ('parameter', function (newValue, oldValue) {// logical processing })
We have created a listener.
The 'parameter' is an object (or an object attribute) under the $ scope object. Note that the parameter is in the string format.
Assume that you want to listen to the $ scope. name attribute.
$ Scope. $ watch ('name', function (newValue, oldValue) {// logical processing })
The above Code requires quotation marks for 'name'
The parameters are followed by the callback function. The callback function parameters return the listener attributes, new values after changes, and old values before changes.
$ Digest
He is responsible for checking whether the data in the scope has changed. If a property changes, the listener of this property will be immediately notified (the listener registered by $ watch), triggering the listener and executing the callback function.
$ Apply
This method is similar to $ digest. $ digest checks all data in the scope.
$ Apply is equivalent to checking all data in rootScope. It checks 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 only triggers a round of $ digest parent-level to child-level loops.
In Angular. js, $ digest is not directly called in a class, but replaced by $ scope. $ apply ().
I have not set a monitor. Why can I bind views and data in two directions?
For example, a text box ng-model = "name"
In this case, the $ scope object already has an attribute name that corresponds to the two-way binding with the preceding view.
How to implement it?
In fact, when we define ng-model = "name" or ng-bind = "name" or {name }}
Angular. js will automatically set a listener for the "name" attribute on the $ scope model:
$ Scope. $ watch ('name', function (newValue, oldValue) {// listen to name attribute changes });
Angular. js automatically creates a listener. Therefore, this attribute and $ scope. name Data are bound in two-way in real time.
Of course, sometimes you will find that the data has changed, but the UI has not been refreshed. Is the bidirectional binding invalid?
No
When the $ scope model traverses the digest loop, your data has not been returned,
For example, the asynchronous call method and the data returned by callbac
For example, if you set a timed trigger function in setTimeout, and then modify the model data
In short, the digest loop of the $ scope model is missed, and the model does not 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 data cyclically and implement bidirectional binding.
As we have already said above, do not directly call the digest method, but manually call the $ apply method to indirectly trigger the $ digest loop.
As follows:
SetTimeout (function () {$ scope. name = 'yijiebuyi'; $ scope. $ apply () ;}, 2000 );
The problem is that you should call the apply method manually.
Currently, angular. js has automatically implemented the $ apply () method for some commands and services.
For example, ng-click, ng-model, $ timeout Service, $ http service, etc.
After the call, angular. js will automatically help us call $ apply () to implement two-way data binding.