The key difference from AngularJS Knockout

mercredi 23 janvier 2013

image Recently, several times I had time to participate in discussions about what Angular better or worse Knockout and other JS-frameworks. And very often I come across the fact that there is some misunderstanding of the differences in the approaches of these products. Sometimes it even goes to the point that as an advantage Knockout cited codes default prefixes «data-», as well, just absolutely ridiculous (not to mention the fact that they can be used in Angular).

I want to fix a time in this article some thoughts on that later you could just give a link. In my opinion, is really the key differences AngularJS from various other frameworks, there are three things in different combinations:

  1. Modular organization of code, testability, and brutal war with any global data.
  2. Propaganda declarative approach through the creation of its own HTML-directives.
  3. Mechanism to verify the data changes in the data bindings without using callbacks.

And the third point here seems to me the most difficult to understand. Let's talk about him.

What is Data Binding? Roughly speaking, this display of data in the template, made so as to change their view changed. With object:
var myViewModel = { personName: 'Bob', personAge: 123 }; 
And ... pattern:
 <span>personName</span> 

... We want to span a change myViewModel updated up to date with our minimal participation. Conversely, if, for example, the input field.

And for this purpose there are two fundamentally different approaches.

Change listeners

For the mechanism of data bindings in such frameworks as Knockout and Backbone system was developed to track changes (change listeners). Do you work with the data not directly, but through a special layer (eg, observables in KO), designed to change the representation of the data in time when they change. Any variable into an object framework that monitors the state.

 var myViewModel = { personName: ko.observable('Bob'), personAge: ko.observable(123) }; ... myViewModel.personName('Mary'); myViewModel.personAge(50); 

 <span data-bind="text: personName"></span> 


Smart and obvious solution. It would seem that the functional and event-oriented programming in javascript is the best suited for such problems, and generally work with callback - our strong horse.

However, there is a problem, which should be solved in this framework.

First, that if one part of the data in some way dependent on the other side? Changing one variable, we automatically inform you about this, but changing the second variable will be obvious. To deal with such dependencies in a mechanism KO dependency tracking, which works well, but the very existence of the solution indicates the existence of a problem.

Secondly, the operation of a system for tracking changes mainly occurs at each change, because basically it's just callbacks. If we change the data continuously or in large portions at once, it will cause a lot of unnecessary alarms, because the ultimate goal - just change the display, one way or another will be given to the final form, and intermediate states are not needed here.

Combining solutions from the previous two paragraphs, we have a third problem: the continuous micro-de-synchronization of all data states. Each time you change something, we call this an appropriate trigger, which in turn may change other data and also trigger. Besides the fact that we are building up so execution stack, we are every moment of time run the risk of starting to work with the data in the process of editing (or prepared for it) somewhere else in the stack, and to properly track such places in the code , you need a good understanding of all the inner workings hidden behind these seemingly simple things, about the same as in multithreaded programming are very sensitive to monitor the use of shared data.

Together, this mechanism data bindings is creating an integrated complex system that the other guys decided to cut the Gordian knot and use a fundamentally different approach.

Dirty checking

According to this principle works AngularJS. Dirty checking - a test of change for the data as a simple two rubles. Before the variable myVar was 1, now it 2 - means the data has changed and they have to be redrawn in the template. For simple variables, this operator, =, to complex - lightweight appropriate procedure. This is the simplest approach, which saves us from both the need to work with data via a special "listening" layer, and all the problems associated with data dependencies.

 var myViewModel = { personName: 'Bob', personAge: 123 }; ... myViewModel.personName = 'Mary'; myViewModel.personAge = 50; 

 <span>{{personName}}</span> 


The question is when to perform this check? Continuously, the timer? Given that the data model can be quite complex, continuously-producing test can greatly impair UX. In Angular this problem is solved by an automatic call to $ digest after each part of the code, presumably able to change the data. This is key - check if and only if the data can be changed (for example, the action of the user), and have never done otherwise. If you expect to change the data in a different point in time (for example, when you receive an event from the server or the completion of a process), you must specify Angular, that is to validate by calling $ Apply .

The data on each iteration of the analysis of all at once, as a whole, and not just some part. Before and after the implementation of $ digest, we have a stable version of the state without desync. If, due to data dependencies any one of them in the verification process has changed, immediately after completion of the current review will be scheduled to run next. And again the next check is made entirely by updating the state of the model completely, eliminating potential problems with unaccounted dependencies.

The obvious disadvantage of this approach - performance. Although there are exceptions: for example, in batch update once a large number of data validation is performed only once at the end, not at each change of each of the tracked objects, as in the first case. But overall, it's still negative, since a change of just one variable in dirty check all the data.

Just need to figure out how strong the performance loss.

It is worth noting that during the implementation of Angular dirty check never works with DOM. All data - is native objects js, with which all modern browsers like lightning engines perform most basic operations. Although you can insert themselves into the process of verification procedures dirty check, documentation Angular strongly recommends working with DOM within them, as this can greatly slow down the whole process.

Given this, we can say that the loss of productivity in today's Web applications in practice is not felt. I used to quite a long time has been developing games for mobile platforms, and there (especially on older like Palm OS) on the account was usually once every clock cycle. But even with such a lack of resources the basic principle of "data bindings" was simply referred to as dirty check. What is Data Binding in the case of the game? This is a display of pictures on the game screen depending on what happens in the state of the game data. Sometimes, indeed, the approach, similar to the approach of listening callback - for example, update the screen only in those places where the picture has changed. But mostly just redraw the screen each time entirely, replacing the current frame of the new state of the current graphics. And the only criterion validity of this approach was and still figure FPS - how often we can change the way images and how smooth is appropriate UX. As long as the FPS is near the maximum possible for the human perception (around 30 frames per second), the loss of speed just does not make sense to think, as they do not lead to anything that could be called the deterioration UX.

The fact is that a simple dirty checking, used in AngularJS, lets you work with data of any complexity, and thus check and change the display of less than 50 ms, and it is at least longer than if we had just checked the data but nevertheless immediately to the user. And while this approach eliminates many different headaches caused by a complex mechanism change listeners, and just easier to work, as we continue to treat data as ordinary variables and POJO-objects instead of using a complex syntax "listen" to the layer.

0 commentaires:

Enregistrer un commentaire

 
© Copyright 2010-2011 GARMOBI All Rights Reserved.
Template Design by Herdiansyah Hamzah | Published by Borneo Templates | Powered by Blogger.com.