Simple Observable 2-way Data binding in JavaScript - javascript

I know a lot of the big name MVC, M** style JavaScript frameworks allow 2-way binding with Observables.
Meaning if I:
Update a DOM input filed, it will also update a JavaScript object variable which could also save to server with AJAX request.
If I update the JavaScript object variable, it will also in turn update the DOM text field.
As I am learning JavaScript, I would love to skip the big name libraries and learn how to do this in it's most basic raw JavaSript form.
Can anyone provide quick easy to understand demo of this functionality without using libraries like BackboneJS, Knockout, Angular, or others?
jQuery is acceptable.
I would appreciate the lesson and help please.

This is different in every framework.
Angular for instance saves every variable on scopes. Iterate through the scopes variables and compare the values with the previous ones and if there is a change it is carried out to the DOM.
This check is made upon they call digest cycles. If one cycle is finished it calls again until every variable 'observed' is the same as it was in the previous cycle. You can also add objects or vars to this 'observer'.
Angular keeping the view current, with calling this digest every time something could change the 'observed' vars, like http calls, user interactions ... but for instance, if you change a variable outside from angular (console), than the variable change is not carried out to the DOM. You have to call a digest cycle manually to do so.
In HTML5 it is a bit easier with Object.observe, but it is not yet supported in every browser currently on the market.
Hope I could help

Related

Do Angular Expressions in view templates slow down angular app performance

My app seems to have views with a lot of logic in them. My question is two fold:
Does logic in the view slow down angular app performance?
As a best practice, is it better to treat this logic in the controller and just store the outcome in a $scope attribute which the view can access ?
Would this improve performance ?
Example of views in our app (a simple one):
<div class="small-12 column" id="notificationMsg">
{{ config.message | translate : config.getMessageParams(notification)}}
</div>
short answer:
yes
long answer:
your bindings will have to be updated in every digest cycle which affects the used variables.
storing the value in a variable and only updating it if something changes will improve your performance.
however this will only be critical if you reach a certain amount of complexity. as long as your app doesn't grow too much this won't be a threat to think about - yet.
i wouldn't necessarily call it a best practice, because it can make your code more complex and harder to read/understand/maintain.
performance isn't always an issue. it just starts to be one as soon as it's absent by default ;)
a further improvement you can do is use ng-bind and ng-bind html instead whenever possible, because it can be rendered faster, since it can skip some internal steps of angularJS whilst compiling the expression.
so e.g. use
<div ng-bind="foo"></div>
instead of
<div>{{ foo }}</div>
if possible
The key concept behind these performance considerations is reducing the number of $$watchers inside Angular to improve the $digest cycle’s performance, something you’ll see and hear more of as you continue working with Angular. These are crucial to keeping our application state fast and responsive for the user. Each time a Model is updated, either through user input in the View, or via service input to the Controller, Angular runs something called a $digest cycle.
This cycle is an internal execution loop that runs through your entire application’s bindings and checks if any values have changed. If values have changed, Angular will also update any values in the Model to return to a clear internal state. When we create data-bindings with AngularJS, we’re creating more $$watchers and $scope Objects, which in turn will take longer to process on each $digest. As we scale our applications, we need to be mindful of how many scopes and bindings we create, as these all add up quickly - each one being checked per $digest loop.
Angular runs every single filter twice per $digest cycle once something has changed. This is some pretty heavy lifting. The first run is from the $$watchers detecting any changes, the second run is to see if there are further changes that need updated values.
Here’s an example of a DOM filter, these are the slowest type of filter, preprocessing our data would be much faster. If you can, avoid the inline filter syntax.
{{ filter_expression | filter : expression : comparator }}
Angular includes a $filter provider, which you can use to run filters in your JavaScript before parsing into the DOM. This will preprocess our data before sending it to the View, which avoids the step of parsing the DOM and understanding the inline filter syntax.
$filter('filter')(array, expression, comparator);
Yes, for better performance, Use
$scope.description: $translate.instant('DESCRIPTION')
in Controller, instead of,
{{'DESCRIPTION' | translate }}
Furthermore,
It depends on what you want to achieve. Here is another way to increase performance.
One Time Binding
Angular 1.3 added :: notation to allow one time binding. In summary, Angular will wait for a value to stabilize after it’s first series of digest cycles, and will use that value to render the DOM element. After that, Angular will remove the watcher forgetting about that binding.

How does AngularJS know when variables change? How does AngularJS dirty checking work?

I was reading some article to understand a little bit more how AngularJS works.
One of the terms that I didn't understand is Dirty Checking.
What is it exactly? It seems like the Observer pattern but apparently it's better.
Can you help me understand this please?
EDIT : it can be also useful for people who wants to learn more about that to watch this video from swiip at NgEurope some years ago.
From this link:
Angular defines a concept of a so called digest
cycle. This cycle can be considered as a loop, during which Angular
checks if there are any changes to all the variables watched by all
the $scopes. So if you have $scope.myVar defined in your controller
and this variable was marked for being watched, then you are
explicitly telling Angular to monitor the changes on myVar in each
iteration of the loop.
This "digest" is also called "dirty checking", because, in a way, it scans the scope for changes. I cannot say if it's for better or for worse than observable pattern. It depends on your needs.
Some links:
Angular documentation
A blog post about Angular scopes
Angular Dirty Checking mechanism workflow.
Dirty checking is a simple process that boils down to a very basic
concept: It checks whether a value has changed that hasn’t yet been
synchronized across the app.
Our Angular app keeps track of the values of the current watches.
Angular walks down the
$watch list, and, if the updated value has not changed from the old
value, it continues down the list. If the value has changed, the app
records the new value and continues down the $watch list.
Check out the whole article here
What is dirty checking?
The process of checking every watch to detect the changes, is called dirty checking. There could be two scenarios
First –
Get a watch from list
Check whether item has been changed
If there is no change in item then
No Action taken, move to next item in watch list
Second–
Get a watch from list
Check whether item has been changed
If there is Change in an item
DOM needs to be updated, return to digest loop
In second case, loop continues till it finds no changes in the entire loop. And once it completes, DOM gets updated if required.
Just modifying a previous answer...
Angular has a concept of ‘digest cycle’. You can consider it as a loop. In which Angular checks if there are any changes to all the variables watched by all the $scopes (internally $watch() and $apply() functions are getting bonded with each variable defined under $scope).
So if you have $scope.myVar defined in your controller (that means this variable myVar was marked for being watched) then you are explicitly telling Angular to monitor the changes on myVar in each iteration of the loop. So when the value of myVar changes, every time $watch() notices and execute $apply() to apply the changes in DOM.
This "Digest" is also called "dirty checking", because, in a way, it scans the scope for changes. As all watched variable are in a single loop (digest cycle), any value change of any variable forces to reassign values of other watched variables in DOM.
PROS: This is the way Angular achieves Two-way data binding.
CONS: If there are more watched variables in a single page (>2000–3000), you may see lag while page loading. (But I say if there are that many ‘watched variables’ in a single page, it is a bad page design :p).
There are other cons, as well as are workarounds also :D
Dirty checking
will check anything changes in $scope variable and update it to the DOM.
This done by angular js, you can also implement dirty checking by your own.
I read a great article about dirty checking in this blog post. There was also this SO answer
TLDR; version
When the $digest cycle kicks in, the watchers will check for any changes in the scope model and if there are any (the change might also come from out-of-Angular-domain), the corresponding listener functions are executed. This will again run the $digest loop and checks if the scope model was changed (the listener function could also modify the scope model).
Overall, the $digest cycle will run twice even if the listener does not change the model or till it hits the max loop count of 10.

Writing to a Firebase from within a Polymer element

I am working on an assignment for a course in "Coding the Humanities" which involves writing a custom web component. This means I am required to use Polymer even though as far as I can see there is absolutely no added value to doing so.
I want to create a literal chat "room" in which users input a character to identify themselves and can walk around the room bumping into one another after the fashion of robotfindskitten.
My idea was to write each character and its position to a Firebase location, updating everyone's positions in real time, so I need the Firebase JS client- using core-ajax for REST requests isn't fast enough.
The GitHub readme for the core-firebase element consists of a link to a less than helpful component page.
Looking at the core-firebase element itself, I don't see anything that corresponds to the 'value' event; locationChanged has a 'child-added' event handler, but that's it.
Am I crazy for thinking the core-firebase element is just very incomplete? Should I try to write my own 'value' handler? If so, do I just add it to the locationChanged property of the object passed to Polymer()? I'm very confused - I know enough JS that what's happening in the core-firebase code is straddling the limits of my comprehension. (Which might have to do with the this keyword, I don't know.) Any input here would be appreciated. (And yes, I've already remarked to the instructor that I could have handled this using plain old jQuery and Firebase if I didn't have to use Polymer. No word as yet on that.)
Looking at the commits for core-firebase it looks like it's had about two days work on it plus some maintenance, so it wouldn't be surprising if there are missing features.
One nice part about Polymer is that it interops very well with other ways of writing apps. It's totally reasonable and supported to use jQuery and Firebase directly to read from firebase and react to changes. You can still make good use of polymer's templating and databinding by doing this within an element of your own and using Polymer's data binding, templating, and plain old DOM events to propagate those changes throughout your app and render them onto the page.

Cache complex directives in AngularJS

I am working on a project targeting mainly mobile devices.
The app receives a list of different objects from the server which shall be rendered all at once.
Each object type has it's own directive, which takes care of business logic. But because most objects share certain features we created 'sub-directives' which work as mixins to keep it DRY.
If more than just a handful of those objects should be displayed (which is the default case), Angular takes quite some time parsing and instantiating those directives + sub-directives.
Our performance improvements so far:
replaced the ng-repeat with a custom directive, which also works like an infinite-scroll
use bindonce to limit bindings only where they are really necessary
pre-fill the $templateCache with the templates, instead of fetching
them via templateUrl
But even with those improvements, the performance is still not acceptable. (Especially when navigating to the state containing the list)
The approach I have in mind now is as follows:
let Angular fully parse and create one such directive with its
sub-directives
cache the resulting node
if we have another object of the same type simple reuse it and link it with a new Scope
But even after going through Angulars source code I have no clue where I could hook in to receive the finished result before advancing to the next object in the list.
So far it parses the template of the actual directive for each entry in the list, then comes back and finishes the sub-directives.
Hope I was able to make it understandable what I am trying to accomplish.
Thanks in advance!

Run javascript on JSON change?

I know enough jQuery/JavaScript to be dangerous. I have a JSON array that I'm interacting with using two different elements (a calendar and a table, to be precise). Is there an event handler (or any other way) I could bind to so that the table would refresh when the JSON changes?
Basic programming, parse the json (=string) into a javascript object or array. (you probably have already done that.) Use an implementation of the observer patern.
I suggest taking a good look at #Adam Merrifield 's interesting links.
Most of the time using getters and setter where you can fire a custom event (or call a callback method) inside a setter is the key in this.
KnockoutJS is a good framework to help you do such binding. It also uses the observable - observer/subscriber pattern.
using timers is not a really good idea.. little to much overhead. (doing stuff also when nothing gets changed. And you will always hop x ms behind (depending on the polling frequency).
You might want to consider Knockout.JS
It allows bi-directional mapping, so a change to your model should reflect on your view and vice/versa.
http://knockoutjs.com/documentation/json-data.html
However, it might be late stages of your dev cycle, but something to consider.

Categories