27

AngularJS offers two-way databinding.

I built several AngularJS apps and found two-way databinding to be a powerful feature, that increased my productivity.

Recently however I come more and more across posts and articles that claim that two-way databinding is an antipattern.

Examples:

Most of the resources argue in favour of "Unidirectional Dataflow" like it is promoted by React/Flux.

Also Angular2 announced for some time that there will be no two-way binding... but the latest documentation shows that it is actually offering two-way databinding via ngModel again (implemented on top of property- and event-binding)

However I do not yet fully understand the problems that relate to two-way databinding in AngularJS.

Other client technologies (i.e. swing, eclipse-rcp, winforms, wpf ...) also offer two-way databinding, and I never stumbled over the claim that it is an anti-pattern ...

Is there a canonical example that easily illustrates the problems that might result from two-way databinding in AngularJS?

The video I linked above seems to hint that $scope.watch is the problem ... but the example can be implemented without $scope.watch by binding to a function exposed on the $scope.
If you avoid using $scope (i.e. using controller as), what problems remain with two-way databinding?

Community
  • 1
  • 1
jbandi
  • 17,499
  • 9
  • 69
  • 81
  • 2
    The thing with two-way binding is that it fires of a cascade of events every time it is triggered. This can get potentially cause a very large amount of overhead on the simpelest actions that are being kept track of. While it isn't directly a bad thing, it is inherently a weakness in any design. Unless you know exactly what you are doing, it is very easy to make sluggish code. AngularJS has been wrestling with that design decision since it's inception and it is a reason why Angular 2 was set up in a different way. Frameworks like React and KnockOut are monodirectional by design. – MartijnK Feb 13 '16 at 12:24
  • @MartijnK Thanks for your comment. Your argument is basically explaining that two-way databinding is poorly implemented in AngularJS ... is this really the reason that the "concept" of two-way databinding is an antipattern? Knockout also offers two-way databinding ... so it's not an anti-pattern when using Knockout as a framework? – jbandi Feb 13 '16 at 12:37
  • 1
    I think anyone who calls two-way binding an anti-pattern would argue that it saves the engineer some time and effort up front at the expense of application performance, maintainability and scalability. In the case of Angular 1.x, each digest cycle triggers a series of dirty checks and callbacks that can quickly get out of hand if you don't understand how and why watches get added. To say that it is an anti-pattern is a harsh criticism IMHO, but I can see why some folks dislike it. – Shaun Scovil Feb 13 '16 at 13:29
  • `$scope.$watch` is for manually creating watches. 2 way data binding creates internal watches – charlietfl Feb 13 '16 at 13:32
  • [Here's a recent good example](https://stackoverflow.com/questions/35377092/how-to-get-around-angulars-performance-issue-with-large-content/35381167#35381167) of how two-way data binding may be flawed in Angular - not the bindings themselves but ngModel implementation. The necessity to filter out parasite values from the other side (see internalChange flag) doesn't add much clarity. – Estus Flask Feb 13 '16 at 15:22

2 Answers2

14

In fact, the main problem with two-way data binding is performance.

When AngularJS was released (1), this feature was the foremost reason why the framework was much used by developers.

Without a line of code, you can make an element fully dynamic by changing its value from the model side or the view side, the value is changed everywhere the model is set.

In this feature, the most important tool is the watching, and it represents all the problem with two-way data binding.

As the application evolves, the number of watchers and watched elements increases.
Also, after a time, the application can become a big soup of watchers.
This will result in your application always watching elements and keeping up-to-date the elements at the inverse side, and that consumes a lot of resources from the browser.

This is why my recommendation is: Avoid watchers as much as possible.
They are almost never really necessary in a controller.

See also :

Hope it's more clear for you.

Johannes Charra
  • 29,455
  • 6
  • 42
  • 51
chalasr
  • 12,971
  • 4
  • 40
  • 82
  • 1
    two-way data binding by itself is not the cause of performance, so the very first statement is true and wrong depending on other factors so it's is wrong. – Ibrahim ben Salah Jun 04 '17 at 11:27
  • 2
    as @MartijnK states in his comment, the cascade of triggered events is basically the problem. Angular.js assumes events are non-pure (i.e may change the state/model) so Angular always assumes all data could have been changed after each event. – Ibrahim ben Salah Jun 04 '17 at 11:39
0

Two-way data binding can be its own problem: a model can update a view which can update a model which can update another model... Unidirectional data flow is more predictable.

Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145