Angularjs 1.3+ One- vs Double Way Data Binding - javascript

I'm new to Angular and it is not clear where the double data binding is needed except from the classic ng-model scenario where the model value is reflected in the view.
Do I need double binding for ng-repeat variables for example? Or do I need it for variables that can be changed in $watch?
I read that one-way data binding can have significant performance improvements so I do not want to use double data binding unless I really need it
For example
<img ng-src="{{mySrc}}"> or
<img ng-src="{{::mySrc}}">
<div ng-repeat="item in items"> or
<div ng-repeat="::item in ::items"> where items retrieved from $http

2-way data binding refers directly to the ng-model directive, it's meaning is that you can change a model value in the view (via an input ng-model) and also change it programmaticly, either change will be replicated to the other and in the view.
ng-repeat is simply an expression that gets evaluated when a digest cycle starts so this is not 2-way data binding.
In terms of performance angulars binding process uses dirty checking and is not ideal, using an ng-model or not will make no difference to this. The digest cycle will only start if the model value changes or if you change a model value in angulars context.
After seeing the code snippet you provided the {{::model}} notation will simply create a one time binding, this means that the value will never change in your view and it won't be watched.
The different is {{value}} gets watched, when it changes this binding gets updated, this is slow on performance due to dirty checking however in your example the value is not watched, it's never checked and if used in a conditional statement is only evaluated once.
It's up to you if you want to use either, if a value will never change then use {{::}} as it's fast, if the values going to change in the future use {{}}

Using double binding is useful only if your model is subjected to constant changes.
In case your model is going to be a constant and doesn't need frequent changes than single binding would be effective.
If you use too many double bindings even where it is not necessary it could lead to serious overhead in AngularJS and can bog down your site. That is because each double binding is monitored via watch by angular.

Related

What does two colons inside an angular expression {{::}} mean?

What is the difference between:
{{::office.name}}
and
{{office.name}}
in angularJS?
One-time binding From Angular Docs.
An expression that starts with :: is considered a one-time expression. One-time expressions will stop recalculating once they are stable, which happens after the first digest if the expression result is a non-undefined value (see value stabilization algorithm below).
In many situations, the values need to be only shown in the view and are never going to update from view or controller. However, if two-way binding is used, $digest will check for any changes in the expression in each cycle, which is not necessary. In these cases, :: should be used before expression. As stated in the above statement, this is more efficient than two-way binding syntax for such cases.
Blog: AngularJS one-time binding syntax from #Todd Motto
In a nut shell, when we declare a value such as {{ ::foo }} inside the DOM, once this value becomes defined, Angular will render it, unbind it from the watchers and thus reduce the volume of bindings inside the $digest loop. Simple!
The {{::office.name}} syntax is Angular's One-Time binding, available since version 1.3
Here's a nice blog explaining it.

Can anyone explain the difference between Reacts one-way data binding and Angular's two-way data binding

I'm a bit fuzzy on these concepts, If I build the same ToDo app completely in AngularJS and ReactJS--- what makes the React ToDo use one-way data binding vs the AngularJS's two-way data binding?
I understand that React sort of works like
Render(data) ---> UI.
How is this different from Angular?
I made a little drawing. I hope it's clear enough. Let me know if it's not !
Angular
When angular sets up databinding two "watchers" exist (this is a simplification)
//js
$scope.name = 'test';
$timeout(function() { $scope.name = 'another' }, 1000);
$timeout(function() { console.log($scope.name); }, 5000);
<!-- html --->
<input ng-model="name" />
The input will start out with test, then update to another in 1000ms. Any changes to $scope.name, either from controller code or by changing the input, will be reflected in the console log 4000ms later. Changes to the <input /> are reflected in the $scope.name property automatically, since ng-model sets up watches the input and notifies $scope of the changes. Changes from the code and changes from the HTML are two-way binding. (Check out this fiddle)
React
React doesn't have a mechanism to allow the HTML to change the component. The HTML can only raise events that the component responds to. The typical example is by using onChange.
//js
render() {
return <input value={this.state.value} onChange={this.handleChange} />
}
handleChange(e) {
this.setState({value: e.target.value});
}
The value of the <input /> is controlled entirely by the render function. The only way to update this value is from the component itself, which is done by attaching an onChange event to the <input /> which sets this.state.value to with the React component method setState. The <input /> does not have direct access to the components state, and so it cannot make changes. This is one-way binding. (Check out this codepen)
Two-way data binding provides the ability to take the value of a property and display it on the view while also having an input to automatically update the value in the model. You could, for example, show the property "task" on the view and bind the textbox value to that same property. So, if the user updates the value of the textbox the view will automatically update and the value of this parameter will also be updated in the controller. In contrast, one way binding only binds the value of the model to the view and does not have an additional watcher to determine if the value in the view has been changed by the user.
Regarding React.js, it was not really designed for two way data binding, however, you can still implement two-way binding manually by adding some additional logic, see for example this link. In Angular.JS two-way binding is a first class citizen, so there is no need to add this additional logic.
What is data binding?
data binding is a general technique that binds data sources from the provider and consumer together and synchronizes them.
Data Biding in Angular
according to AngularJs documents, Data-binding in AngularJS apps is the automatic synchronization of data between the model and view components. The view is a projection of the model at all times. When the model changes, the view reflects the change, and vice versa
the template (which is the uncompiled HTML along with any additional markup or directives) is compiled on the browser. The compilation step produces a live view. Any changes to the view are immediately reflected in the model, and any changes in the model are propagated to the view.
Data Binding in ReactJs
The connection between the data to be displayed in the view and the component’s logic is called data binding in ReactJS. ReactJS uses one-way data binding.
In one-way data binding one of the following conditions can be followed:
Component to View: Any change in component data would get reflected in the view.
View to Component: Any change in View would get reflected in the component’s data.
read more here and here.
While React doesn't provide two-way data bindings out of the box, there are many use cases for which they seem like the natural state management mechanism to work with -- especially when working on complex single-page or React Native applications or with lots of asynchronously coordinated data, transformations, and logic.
react-bindings adds convenient two-way bindings support and tools for React / React Native and react-waitables builds on top of it with additional async support. These packages, especially used in combination with React hooks and contexts, mean not having to choose strictly between unidirectional and bidirectional models just because of working with React vs Angular.
One way data binding is very simple, except in React we rarely use the word binding to refer how the data flows.
const fn = (a) => { return ... }
If a value is provided as a, we'll use that value in the function scope. The above is programming 101.
<Title name={"Hello"} />
The above line doesn't mean anything would magically happen other than the fact that "Hello" is sent to Title function and set one prop to "Hello", if you insist to use the word bind here, that's where the bind happens.
Whether you want to use this prop to display or wire with another state or whatever, you have to code yourself! There's no other magic. Btw, this is called props in React. And props is more or less a function's input argument coded in an object format. So the more accurate definition of this "bind" in React should be called assignment. In React source code, you'll see something very quickly after the element is created.
element.props = { name: "Hello" }
And believe it or not, there's no other code in React that does anything to do with this "bind" later on.
Example
Use the input example,
<input value={value} onChange={onChange} />
If we give a value to input, the input would pick up the value to display it. If you change the value, you are intending to change the display.
Why does the value change? It can't by default. You have to change it by either listening to a system event like onChange or some business logic like setTimeout or whatever way you can ever imagine. But the change is an action, you perform the action therefore you can handle the action by changing the value. I guess this is where the "One-way" comes from. Essentially nothing is free.
Confusion
What gets us confused is that DOM element has its own state or properties. For example, we can do el.textContent="abc" without using React.
<input />
If we just code like this, we still see the value on screen changes after we type in anything. But this behavior has nothing to do with React, it's the DOM element functionalities. React refers to the first version as controlled element. Essentially React overwrites the DOM way.
NOTE
To be honest, only after I stopped using the word "binding" for these cases, I started to understand what they are. But that could be just me.

ng-init vs function in controller, which is better practice when using $parent?

I have a Bootstrap modal which corresponds to a ng-repeat list. I would like to access the ng-repeat scope data from its parent, which contains the modal. I do this so that when the modal button is clicked on the list, the corresponding data from the JSON appears in the modal.
I have found 2 ways of doing this, and I wonder which is the best alternative?
Method 1
View:
<li ng-init="myFunction(item,$parent)" ng-repeat="item in data.webapps_1.items>
Controller:
$scope.myFunction = function(item,parent){
parent.selected=item.counter-1;
};
Method 2 View:
<li ng-init="$parent.selected=item.counter-1" ng-repeat="item in data.webapps_1.items>
With nothing in the controller.
I have read in the Angular ngInit docs that
The only appropriate use of ngInit is for aliasing special properties
of ngRepeat, as seen in the demo below. Besides this case, you should
use controllers rather than ngInit to initialize values on a scope.
But the list of special properties of ngRepeat does not include $parent.
So, which is the better practice? Including the expression $parent.selected=item.counter-1in the controller or in ngInit directive?
Thanks in advance
Either of the two fine really, so long as you're consistent. Depends on the scale of the app though.
IMO if the app is going to be large you'll want to go the function way, to better adhere to the whole MVC philosophy of decoupling and separation of concerns (http://victorblog.com/2013/03/18/angularjs-separation-of-concerns/).
ng-init="myFunction(item,$parent)"
It's a better structure because you want to keep most of your business logic in the javascript controllers, not in the view.
Personally, I prefer the ng-init approach. Mainly for consistency of the timing of the call (i.e. more like an "onLoad" event). I understand the concerns regarding SoC and that makes sense as well. However, I have seen some specific scenarios (particularly pages with a lot of directives), when changing scope variables with the = binding in the (non ng-init) function, caused extra (premature) digest loops. Obviously it depends on what you're actually doing in the function as well as your scope bindings, but in my opinion its best to just avoid the situation and use the ng-init directive across the board. Your experience may obviously vary wildly. Like others said just pick an approach and stick with it and be aware of the impact of every call that you're making in the function itself. :)
EDIT: Regarding the accepted answer, the example was used passing values to the init function in ng-init. And hes correct that is a violation of the pattern. I typically use parameterless init functions and call it like:
ng-init="model.init()"
Any reference to $scope or what have you would happen inside the function itself. I rarely pass anything to init, unless its a static value. For example in several cases on an ASP.NET WebApi project, I wanted minimize round trips to the server so I would resolve a value from the MVC View Model, which is just rendered and passed as a string like so:
ng-init="model.init(#model.myValue)"
In those cases its usually best to keep it to simple value types (i.e. string, int, etc), but I have occasionally for small directives such as one that does nothing but display a dropdown, I have passed arrays to pre-populate the dropdown binding. Those cases are extremely situational and this one in particular would obviously only work when using server side rendering of the template.

Directives callbacks and scope

I'm trying to wrap my head around scopes in angularjs, particularly when it comes to invoking callbacks on the module that is using a directive. I've found 3 different ways to accomplish the same thing and I'm trying to understand the pros/cons to each approach.
Given this plnkr
When is it appropriate to use &, =, or calling functions directly on the parent?
I prefer binding with the '=' sign, as there is less code required in the directive and in the module hosting the directive, but according to the documentation (Understanding Transclusion and Scopes) it seems that binding to callbacks with the & is the preferred method, why?
Good question. These kinds of decisions should be made first from the perspective of trying to separate your concerns. So we have to eliminate calling a method on the parent scope - the directive has to know too much about the parent.
Next, we look at purpose. Callbacks are methods by definition. & evaluates an expression in the context of the parent scope, while a bi-directional binding is just a variable name. & is a lot more powerful and gives the user of your directive more flexibility. Sure, they could do this, like in your example:
<my-dir cb="callMe()"></my-dir>
But they could also do this:
<my-dir cb="myVar = false"></my-dir>
We don't have to pass in the name of a variable - it's any AngularJS expression. So the user of the component is free to react to your event in any way that suits them. Awesome!
But also, the directive can react to state changes. For example, you could check for a condition:
<my-dir cb="myVar"></my-dir>
And myVar can evaluate to any value and your directive can be made aware anytime this changes and react accordingly. Instead of sharing a variable, you're sharing an expression. In this case, a bi-directional binding would work, but if the directive doesn't (and maybe shouldn't) change that variable, why do we need a two-way binding?
But again, it needn't be a variable. How about a expression that evaluates to true or false?
<my-dir cb="myVar == myOtherVar"></my-dir>
Our directive doesn't have to care how the parent scope arrives at a value - only what the value eventually is.
So we can use it for the parent scope to react to the directive or for the directive to react to the parent - all with flexible expressions. Neat.
So, = is for ensuring data binding; it ensures that the scope where the directive was used and the directive itself stay in sync on a certain variable. & allows for evaluating expressions in the context of the parent scope and for either the directive or the parent scope to react to potentially complex state changes.

How does data binding work in AngularJS?

How does data binding work in the AngularJS framework?
I haven't found technical details on their site. It's more or less clear how it works when data is propagated from view to model. But how does AngularJS track changes of model properties without setters and getters?
I found that there are JavaScript watchers that may do this work. But they are not supported in Internet Explorer 6 and Internet Explorer 7. So how does AngularJS know that I changed for example the following and reflected this change on a view?
myobject.myproperty="new value";
AngularJS remembers the value and compares it to a previous value. This is basic dirty-checking. If there is a change in value, then it fires the change event.
The $apply() method, which is what you call when you are transitioning from a non-AngularJS world into an AngularJS world, calls $digest(). A digest is just plain old dirty-checking. It works on all browsers and is totally predictable.
To contrast dirty-checking (AngularJS) vs change listeners (KnockoutJS and Backbone.js): While dirty-checking may seem simple, and even inefficient (I will address that later), it turns out that it is semantically correct all the time, while change listeners have lots of weird corner cases and need things like dependency tracking to make it more semantically correct. KnockoutJS dependency tracking is a clever feature for a problem which AngularJS does not have.
Issues with change listeners:
The syntax is atrocious, since browsers do not support it natively. Yes, there are proxies, but they are not semantically correct in all cases, and of course there are no proxies on old browsers. The bottom line is that dirty-checking allows you to do POJO, whereas KnockoutJS and Backbone.js force you to inherit from their classes, and access your data through accessors.
Change coalescence. Suppose you have an array of items. Say you want to add items into an array, as you are looping to add, each time you add you are firing events on change, which is rendering the UI. This is very bad for performance. What you want is to update the UI only once, at the end. The change events are too fine-grained.
Change listeners fire immediately on a setter, which is a problem, since the change listener can further change data, which fires more change events. This is bad since on your stack you may have several change events happening at once. Suppose you have two arrays which need to be kept in sync for whatever reason. You can only add to one or the other, but each time you add you fire a change event, which now has an inconsistent view of the world. This is a very similar problem to thread locking, which JavaScript avoids since each callback executes exclusively and to completion. Change events break this since setters can have far-reaching consequences which are not intended and non obvious, which creates the thread problem all over again. It turns out that what you want to do is to delay the listener execution, and guarantee, that only one listener runs at a time, hence any code is free to change data, and it knows that no other code runs while it is doing so.
What about performance?
So it may seem that we are slow, since dirty-checking is inefficient. This is where we need to look at real numbers rather than just have theoretical arguments, but first let's define some constraints.
Humans are:
Slow — Anything faster than 50 ms is imperceptible to humans and thus can be considered as "instant".
Limited — You can't really show more than about 2000 pieces of information to a human on a single page. Anything more than that is really bad UI, and humans can't process this anyway.
So the real question is this: How many comparisons can you do on a browser in 50 ms? This is a hard question to answer as many factors come into play, but here is a test case: http://jsperf.com/angularjs-digest/6 which creates 10,000 watchers. On a modern browser this takes just under 6 ms. On Internet Explorer 8 it takes about 40 ms. As you can see, this is not an issue even on slow browsers these days. There is a caveat: The comparisons need to be simple to fit into the time limit... Unfortunately it is way too easy to add a slow comparison into AngularJS, so it is easy to build slow applications when you don't know what you are doing. But we hope to have an answer by providing an instrumentation module, which would show you which are the slow comparisons.
It turns out that video games and GPUs use the dirty-checking approach, specifically because it is consistent. As long as they get over the monitor refresh rate (typically 50-60 Hz, or every 16.6-20 ms), any performance over that is a waste, so you're better off drawing more stuff, than getting FPS higher.
Misko already gave an excellent description of how the data bindings work, but I would like to add my view on the performance issue with the data binding.
As Misko stated, around 2000 bindings are where you start to see problems, but you shouldn't have more than 2000 pieces of information on a page anyway. This may be true, but not every data-binding is visible to the user. Once you start building any sort of widget or data grid with two-way binding you can easily hit 2000 bindings, without having a bad UX.
Consider, for example, a combo box where you can type text to filter the available options. This sort of control could have ~150 items and still be highly usable. If it has some extra feature (for example a specific class on the currently selected option) you start to get 3-5 bindings per option. Put three of these widgets on a page (e.g. one to select a country, the other to select a city in the said country, and the third to select a hotel) and you are somewhere between 1000 and 2000 bindings already.
Or consider a data-grid in a corporate web application. 50 rows per page is not unreasonable, each of which could have 10-20 columns. If you build this with ng-repeats, and/or have information in some cells which uses some bindings, you could be approaching 2000 bindings with this grid alone.
I find this to be a huge problem when working with AngularJS, and the only solution I've been able to find so far is to construct widgets without using two-way binding, instead of using ngOnce, deregistering watchers and similar tricks, or construct directives which build the DOM with jQuery and DOM manipulation. I feel this defeats the purpose of using Angular in the first place.
I would love to hear suggestions on other ways to handle this, but then maybe I should write my own question. I wanted to put this in a comment, but it turned out to be way too long for that...
TL;DR
The data binding can cause performance issues on complex pages.
By dirty checking the $scope object
Angular maintains a simple array of watchers in the $scope objects. If you inspect any $scope you will find that it contains an array called $$watchers.
Each watcher is an object that contains among other things
An expression which the watcher is monitoring. This might just be an attribute name, or something more complicated.
A last known value of the expression. This can be checked against the current computed value of the expression. If the values differ the watcher will trigger the function and mark the $scope as dirty.
A function which will be executed if the watcher is dirty.
How watchers are defined
There are many different ways of defining a watcher in AngularJS.
You can explicitly $watch an attribute on $scope.
$scope.$watch('person.username', validateUnique);
You can place a {{}} interpolation in your template (a watcher will be created for you on the current $scope).
<p>username: {{person.username}}</p>
You can ask a directive such as ng-model to define the watcher for you.
<input ng-model="person.username" />
The $digest cycle checks all watchers against their last value
When we interact with AngularJS through the normal channels (ng-model, ng-repeat, etc) a digest cycle will be triggered by the directive.
A digest cycle is a depth-first traversal of $scope and all its children. For each $scope object, we iterate over its $$watchers array and evaluate all the expressions. If the new expression value is different from the last known value, the watcher's function is called. This function might recompile part of the DOM, recompute a value on $scope, trigger an AJAX request, anything you need it to do.
Every scope is traversed and every watch expression evaluated and checked against the last value.
If a watcher is triggered, the $scope is dirty
If a watcher is triggered, the app knows something has changed, and the $scope is marked as dirty.
Watcher functions can change other attributes on $scope or on a parent $scope. If one $watcher function has been triggered, we can't guarantee that our other $scopes are still clean, and so we execute the entire digest cycle again.
This is because AngularJS has two-way binding, so data can be passed back up the $scope tree. We may change a value on a higher $scope that has already been digested. Perhaps we change a value on the $rootScope.
If the $digest is dirty, we execute the entire $digest cycle again
We continually loop through the $digest cycle until either the digest cycle comes up clean (all $watch expressions have the same value as they had in the previous cycle), or we reach the digest limit. By default, this limit is set at 10.
If we reach the digest limit AngularJS will raise an error in the console:
10 $digest() iterations reached. Aborting!
The digest is hard on the machine but easy on the developer
As you can see, every time something changes in an AngularJS app, AngularJS will check every single watcher in the $scope hierarchy to see how to respond. For a developer this is a massive productivity boon, as you now need to write almost no wiring code, AngularJS will just notice if a value has changed, and make the rest of the app consistent with the change.
From the perspective of the machine though this is wildly inefficient and will slow our app down if we create too many watchers. Misko has quoted a figure of about 4000 watchers before your app will feel slow on older browsers.
This limit is easy to reach if you ng-repeat over a large JSON array for example. You can mitigate against this using features like one-time binding to compile a template without creating watchers.
How to avoid creating too many watchers
Each time your user interacts with your app, every single watcher in your app will be evaluated at least once. A big part of optimising an AngularJS app is reducing the number of watchers in your $scope tree. One easy way to do this is with one time binding.
If you have data which will rarely change, you can bind it only once using the :: syntax, like so:
<p>{{::person.username}}</p>
or
<p ng-bind="::person.username"></p>
The binding will only be triggered when the containing template is rendered and the data loaded into $scope.
This is especially important when you have an ng-repeat with many items.
<div ng-repeat="person in people track by username">
{{::person.username}}
</div>
This is my basic understanding. It may well be wrong!
Items are watched by passing a function (returning the thing to be
watched) to the $watch method.
Changes to watched items must be made within a block of code
wrapped by the $apply method.
At the end of the $apply the $digest method is invoked which goes
through each of the watches and checks to see if they changed since
last time the $digest ran.
If any changes are found then the digest is invoked again until all changes stabilize.
In normal development, data-binding syntax in the HTML tells the AngularJS compiler to create the watches for you and controller methods are run inside $apply already. So to the application developer it is all transparent.
I wondered this myself for a while. Without setters how does AngularJS notice changes to the $scope object? Does it poll them?
What it actually does is this: Any "normal" place you modify the model was already called from the guts of AngularJS, so it automatically calls $apply for you after your code runs. Say your controller has a method that's hooked up to ng-click on some element. Because AngularJS wires the calling of that method together for you, it has a chance to do an $apply in the appropriate place. Likewise, for expressions that appear right in the views, those are executed by AngularJS so it does the $apply.
When the documentation talks about having to call $apply manually for code outside of AngularJS, it's talking about code which, when run, doesn't stem from AngularJS itself in the call stack.
Explaining with Pictures :
Data-Binding needs a mapping
The reference in the scope is not exactly the reference in the template. When you data-bind two objects, you need a third one that listen to the first and modify the other.
Here, when you modify the <input>, you touch the data-ref3. And the classic data-bind mecanism will change data-ref4. So how the other {{data}} expressions will move ?
Events leads to $digest()
Angular maintains a oldValue and newValue of every binding. And after every Angular event, the famous $digest() loop will check the WatchList to see if something changed. These Angular events are ng-click, ng-change, $http completed ... The $digest() will loop as long as any oldValue differs from the newValue.
In the previous picture, it will notice that data-ref1 and data-ref2 has changed.
Conclusions
It's a little like the Egg and Chicken. You never know who starts, but hopefully it works most of the time as expected.
The other point is that you can understand easily the impact deep of a simple binding on the memory and the CPU. Hopefully Desktops are fat enough to handle this. Mobile phones are not that strong.
Obviously there is no periodic checking of Scope whether there is any change in the Objects attached to it. Not all the objects attached to scope are watched . Scope prototypically maintains a $$watchers . Scope only iterates through this $$watchers when $digest is called .
Angular adds a watcher to the $$watchers for each of these
{{expression}} — In your templates (and anywhere else where there’s an expression) or when we define ng-model.
$scope.$watch(‘expression/function’) — In your JavaScript we can just attach a scope object for angular to watch.
$watch function takes in three parameters:
First one is a watcher function which just returns the object or we can just add an expression.
Second one is a listener function which will be called when there is a change in the object. All the things like DOM changes will be implemented in this function.
The third being an optional parameter which takes in a boolean . If its true , angular deep watches the object & if its false Angular just does a reference watching on the object.
Rough Implementation of $watch looks like this
Scope.prototype.$watch = function(watchFn, listenerFn) {
var watcher = {
watchFn: watchFn,
listenerFn: listenerFn || function() { },
last: initWatchVal // initWatchVal is typically undefined
};
this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers
};
There is an interesting thing in Angular called Digest Cycle. The $digest cycle starts as a result of a call to $scope.$digest(). Assume that you change a $scope model in a handler function through the ng-click directive. In that case AngularJS automatically triggers a $digest cycle by calling $digest().In addition to ng-click, there are several other built-in directives/services that let you change models (e.g. ng-model, $timeout, etc) and automatically trigger a $digest cycle. The rough implementation of $digest looks like this.
Scope.prototype.$digest = function() {
var dirty;
do {
dirty = this.$$digestOnce();
} while (dirty);
}
Scope.prototype.$$digestOnce = function() {
var self = this;
var newValue, oldValue, dirty;
_.forEach(this.$$watchers, function(watcher) {
newValue = watcher.watchFn(self);
oldValue = watcher.last; // It just remembers the last value for dirty checking
if (newValue !== oldValue) { //Dirty checking of References
// For Deep checking the object , code of Value
// based checking of Object should be implemented here
watcher.last = newValue;
watcher.listenerFn(newValue,
(oldValue === initWatchVal ? newValue : oldValue),
self);
dirty = true;
}
});
return dirty;
};
If we use JavaScript’s setTimeout() function to update a scope model, Angular has no way of knowing what you might change. In this case it’s our responsibility to call $apply() manually, which triggers a $digest cycle. Similarly, if you have a directive that sets up a DOM event listener and changes some models inside the handler function, you need to call $apply() to ensure the changes take effect. The big idea of $apply is that we can execute some code that isn't aware of Angular, that code may still change things on the scope. If we wrap that code in $apply , it will take care of calling $digest(). Rough implementation of $apply().
Scope.prototype.$apply = function(expr) {
try {
return this.$eval(expr); //Evaluating code in the context of Scope
} finally {
this.$digest();
}
};
AngularJS handle data-binding mechanism with the help of three powerful functions : $watch(),$digest()and $apply(). Most of the time AngularJS will call the $scope.$watch() and $scope.$digest(), but
in some cases you may have to call these functions manually to update with new values.
$watch() :-
This function is used to observe changes in a variable on the $scope.
It accepts three parameters: expression, listener and equality object,
where listener and equality object are optional parameters.
$digest() -
This function iterates through all the watches in the $scope object,
and its child $scope objects
(if it has any). When $digest() iterates
over the watches, it checks if the value of the expression has
changed. If the value has changed, AngularJS calls the listener with
new value and old value. The $digest() function is called
whenever AngularJS thinks it is necessary. For example, after a button
click, or after an AJAX call. You may have some cases where AngularJS
does not call the $digest() function for you. In that case you have to
call it yourself.
$apply() -
Angular do auto-magically updates only those model changes which are
inside AngularJS context. When you do change in any model outside of
the Angular context (like browser DOM events, setTimeout, XHR or third
party libraries), then you need to inform Angular of the changes by
calling $apply() manually. When the $apply() function call finishes
AngularJS calls $digest() internally, so all data bindings are
updated.
It happened that I needed to link a data model of a person with a form, what I did was a direct mapping of the data with the form.
For example if the model had something like:
$scope.model.people.name
The control input of the form:
<input type="text" name="namePeople" model="model.people.name">
That way if you modify the value of the object controller, this will be reflected automatically in the view.
An example where I passed the model is updated from server data is when you ask for a zip code and zip code based on written loads a list of colonies and cities associated with that view, and by default set the first value with the user. And this I worked very well, what does happen, is that angularJS sometimes takes a few seconds to refresh the model, to do this you can put a spinner while displaying the data.
The one-way data binding is an approach where a value is taken from the data model and inserted into an HTML element. There is no way to update model from view. It is used in classical template systems. These systems bind data in only one direction.
Data-binding in Angular apps is the automatic synchronisation of data between the model and view components.
Data binding lets you treat the model as the single-source-of-truth in your application. The view is a projection of the model at all times. If the model is changed, the view reflects the change and vice versa.
Here is an example of data binding with AngularJS, using an input field. I will explain later
HTML Code
<div ng-app="myApp" ng-controller="myCtrl" class="formInput">
<input type="text" ng-model="watchInput" Placeholder="type something"/>
<p>{{watchInput}}</p>
</div>
AngularJS Code
myApp = angular.module ("myApp", []);
myApp.controller("myCtrl", ["$scope", function($scope){
//Your Controller code goes here
}]);
As you can see in the example above, AngularJS uses ng-model to listen and watch what happens on HTML elements, especially on input fields. When something happens, do something. In our case, ng-model is bind to our view, using the mustache notation {{}}. Whatever is typed inside the input field is displayed on the screen instantly. And that's the beauty of data binding, using AngularJS in its simplest form.
Hope this helps.
See a working example here on
Codepen
AngularJs supports Two way data-binding.
Means you can access data View -> Controller & Controller -> View
For Ex.
1)
// If $scope have some value in Controller.
$scope.name = "Peter";
// HTML
<div> {{ name }} </div>
O/P
Peter
You can bind data in ng-model Like:-
2)
<input ng-model="name" />
<div> {{ name }} </div>
Here in above example whatever input user will give, It will be visible in <div> tag.
If want to bind input from html to controller:-
3)
<form name="myForm" ng-submit="registration()">
<label> Name </lbel>
<input ng-model="name" />
</form>
Here if you want to use input name in the controller then,
$scope.name = {};
$scope.registration = function() {
console.log("You will get the name here ", $scope.name);
};
ng-model binds our view and render it in expression {{ }}.
ng-model is the data which is shown to the user in the view and with which the user interacts.
So it is easy to bind data in AngularJs.
Angular.js creates a watcher for every model we create in view. Whenever a model is changed, an "ng-dirty" class is appeneded to the model, so the watcher will observe all models which have the class "ng-dirty" & update their values in the controller & vice versa.
data binding:
What is data binding?
Whenever the user changes the data in the view , there occurs an update of that change in the scope model, and viceversa.
How is it possible?
Short answer :
With the help of digest cycle.
Description :
Angular js sets the watcher on the scope model, which fires the listener function if there is a change in the model.
$scope.$watch('modelVar' , function(newValue,oldValue){
//Dom update code with new value
});
So When and How is the watcher function called?
Watcher function is called as part of the digest cycle.
Digest cycle is called automatically triggered as part of angular js built in directives/services like ng-model , ng-bind , $timeout, ng-click and others.. that let you trigger the digest cycle.
Digest cycle function:
$scope.$digest() -> digest cycle against the current scope.
$scope.$apply() -> digest cycle against the parent scope
i.e$rootScope.$apply()
Note:
$apply() is equal to $rootScope.$digest() this means the dirty checking starts right from the root or top or the parent scope down to all the child $scopes in the angular js application.
The above features work in the browsers IE for the mentioned versions also just by making sure your application is angular js application which means you are using the angularjs framework script file referenced in the script tag.
Thank you.

Categories

Resources