Ember.js observables. So you like to watch!

Filed under: Ember.js

comments (12) Views: 6,367

Ember.js is the bee's knees. It has 2 way data-bindings, computed properties, and templating (built in). But another cool feature of Ember.js is observables. Observable allow one piece of code to watch another piece of code for changes. When the change happens the "watching" code fires and performs it's specified action. Let's take a look at how easy it is to add this behaviour with Ember.js. First the code: since this example is so simple I've combined the HTML and JS portions into one.

You can see that the HTML references a view, in this case a TextField. We then create our Application, and define the TextField view by adding a single additional method: valueDidChange. There's nothing special about this method by itself, but what's chained on to the end is what does the heavy lifting. The .observes() method takes a single argument commadelimited list of arguments, the value/properties you wish to watch. It then waits, just like Chuck Norris, for those value/properties change and then it leaps into action...and fires an alert box.

Bit of a letdown innit? That particular functionality isn't all that useful so let's build one of our own. Something useful, perhaps a text countdown for a textarea field...the kind Twitter uses. This example is also simple so again let's take a look at the code, and see what it does. Update: The following Gist changed based on Peter's comments listed below. Specifically point #3.

We've already looked at .observes() so next we're focusing on what gets passed into our valueDidChange function. Notice that I've added 3 arguments to the valueDidChange function (watcher, property, value). Watcher is a reference to the element which changed doing the watching, property is a string containing the name of the property being watched, and value contains the current value of "property". In the case of a TextArea field value is a string.

Let's a take a quick step back to the Application definition. In past articles we had an empty Application.create() block, but in this instance we're defining a variable called len. We're setting that number to the "maximum" string length we want our textarea to hold. Then, when someone types into it we simply subtract the length of the value from 140. After we get the new value we have to update App.len. Every object in Ember has a get and a set method (sometimes called getters and setters). You call App.set(), tell it what property you're wanting to change, and then provide a new value. Done. In the view for this app, you can see a lone span tag. Inside the span we reference the current value of App.len. When that value changes, so does the contents of the span tag. Ember is magic I tell you!

Amazon logo

If this article was interesting, or helpful, or even wrong, please consider leaving a comment, or buying something from my wishlist. It's appreciated!

I think your second demo link is wrong. The jsfiddle is missing most of the code.

Raymond Camden - March 27, 2012 05:39 am

That's one of the things I don't like about JS Fiddle. I assume that when I've run the code (and I get a custom URL) that the code has been saved. That's burned me a few times. Thanks for letting me know.

andy matthews - March 27, 2012 10:07 am

Thanks for writing this! A few points of clarification:

1) The `observes` method actually can take more than one argument. Each argument passed is another property name or path. If any of these changes, the observer will trigger. For instance, if you do `observes('valueOne', 'valueTwo')` the observer will trigger if either "valueOne" or "valueTwo" changes.

2) You named the first argument for the observing method "element". This is a bit misleading since it's not a DOMElement, but the object that is observing. In most cases it will be the object that the method is defined on it. In this case, it will be the TextArea subclass.

3) Ember naming convention (which we've admittedly not been the best about conveying) is to name instances with lowercase and classes with uppercase. Since `myInput` is a class (you used `extend`), you should probably name it as `MyInput`.

Anyway, thanks again. I really appreciate seeing more articles about Ember.

Peter Wagenet - March 28, 2012 11:23 am

Thanks for taking the time to comment Peter. I'm really loving Ember and I'm excited about an MVC framework for the first time in years. With other frameworks I had to struggle to understand the concepts and the code, but with Ember I just get it.

andy matthews - March 29, 2012 09:27 am

Really enjoy reading your articles. I'm just getting back into Javascript and am learning Ember.js so your "documentation" has been very helpful in clarifying some of the cobwebs. Thanks!

Ty - April 04, 2012 05:17 pm

Thanks Ty! Glad you like it. Keep your eyes open for an article about Ember that I'm writing for Adobe. It's an exhaustive getting started with Ember walkthrough. I think you'll like it.

andy matthews - April 05, 2012 08:15 pm

Thanks Andy.. I was struggling to write my first App with Ember.. using Ember's doc.. but wasnt helping me.. but your small example, made my day.. !! again Thank you so much..!...

Please let me know if you are posting more articles else where....

Chintan Patel - May 23, 2012 09:11 pm

Chintan...

I wrote an article about Ember for Adobe's Devnet. That might be another good one for you to read:

http://www.adobe.com/devnet/html5/articles/flame-on-a-beginners-guide-to-emberjs.html

andy matthews - May 25, 2012 02:38 pm

Thanks for your post!

Im new to Ember, and I was a bit confused about the syntax here. Where do you actually call valueDidChange? also, where is it declared that the observed "value" is the len? is it based on the fact that you're working with a TextArea?

What if you had multiple methods in App.MyInput, how would a specific one get called?

Thanks for your time,
A

Aaron Krolik - September 06, 2012 12:42 pm

Aaron...

1) valueDidChange is automatically called. It adds a listener to the textarea for the keyup event.

2) The observed value isn't the len. len is a key within the App object. Ember uses getters/setters to interact with values within itself.

3) While valueDidChange is called automatically, you could easily add other methods that could be called arbitrarily. For example you could colorize the background of the textarea when the counter reaches a certain threshold:

colorize: function() {
// do something here;
}

Then call it from anywhere: App,MyInput.colorize();

Finally everything in this blog post could have changed since I've written it. Ember isn't yet on 1.0 and it's been through quite a rollercoaster in terms of updates. Check the documentation for the version you happen to be using to be sure.

andy matthews - September 06, 2012 10:35 pm

Your articles on Ember are always awesome.....!!! I have started to learn Ember by studying your articles. They are awesome..

Thank you...!!!

Hemang - October 19, 2012 01:37 pm

Thank you Hernang!

andy matthews - October 25, 2012 11:52 am