Getting started with Ember.js

January 31, 2013

Here's a quick guide to some code which accesses a redis database via webdis and then displays all the keys it finds. It also provides an option to delete keys from the database. In these code examples, webdis is accessed at http://localhost:7379/

Webdis

We're using webdis to access redis, which returns information about the data in redis using JSON.

http://localhost:7379/LIST/* lists all keys in Redis.

{"KEYS": {"KEYS":["key2","key","key1"]}

http://localhost:7379/GET/key returns the value of a key.

{"GET":"valueOfKey"}

http://localhost:7379/DEL/key deletes a key

{"DEL":1}

APP.JS

This first bit of code in app.js creates the application. It also includes a callback that runs when the page is ready, just like jQuery.

App = Em.Application.create({
  ready: function() {
      // Run when the page is ready 
      App.configController.loadKeys();
  }
}) ;

Next we define an object to hold our key/value pair

App.KeyValue = Em.Object.extend({ 
   key: null,
   value: null
});

Next we define our controller. This will manage a set of KeyValue instances.

content is the list of KeyValue instances

deleteKey is a function run from the view when the [delete] link is clicked on the page.

loadKeys is a function run from the application ready callback to load up the initial list of key/values from redis.

App.configController = Em.ArrayController.create({

  content : [],  // holds list of Key/value pairs

  deleteKey : function(view){ // called from view to delete key
    var me=this; // Get hold of this (it changes in the callback)
    var delUrl = 'http://localhost:7379/del/' + view.context.key;
    $.getJSON(delUrl,function(pDeleteResult){ // Remove key from Redis
      console.log(view.context.key); 
      me.removeObject(view.context); // remove object from content collection
    });

  },
  loadKeys: function() { // Load all keys from redis
    console.log("Loading keys...");
    var me = this;

    var keysUrl = 'http://localhost:7379/keys/*';
    var keyUrl = 'http://localhost:7379/get/';

    $.getJSON(keysUrl,function(pKeysData){
      me.set('content', []); // clear out existing keys
      console.log(pKeysData.keys);
      $(pKeysData.keys).each(function(index, pKeyName){ // for each key
        console.log(pKeyName);
        var lKeyValue;
        $.getJSON(keyUrl + pKeyName,function(pKeyData){ // get key value
            lKeyValue = pKeyData.get
            console.log(lKeyValue);

            // Create object with key/value pair
           var t = App.KeyValue.create({ 
                key: pKeyName, 
                value: lKeyValue
            });

            me.pushObject(t); // add object to list this object holds

        });
      });
    });
  } 
});

The loadKeys function fetches all the keys from Redis, and then loops through the keys returned fetching the value for each key. It then creates a new App.KeyValue instance with the appropriate key and value and then adds that new object to the list stored on the controller.

INDEX.HTML

The HTML file loads jQuery and ember (ember depends on jQuery) and then loads the app.js file.

Next we use Mustache template to loop through the KeyValue pair objects on the configController, outputting the key and value attributes into the HTML.

We then have a delete link which calls the deleteKey() function on the configController.

<!DOCTYPE html>
<html>
<head>
   <title>Redis Keys</title>
   <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
   <script src="http://cloud.github.com/downloads/emberjs/ember.js/ember-0.9.6.min.js"></script>
   <script src="app.js"></script>
</head>
<body>
   <script type="text/x-handlebars">
      <div id="content">
         <div id="tweets">
            <ul> 
              {{#each App.configController}} 
              <li> 
                <p>{{key}} = {{value}} 
                    [<a href="#" title="delete this key" {{action "deleteKey" target="App.configController"}}>delete</a>]</p>
              </li> 
             {{/each}} 
           </ul>
         </div>
      </div>
   </script>
</body>
</html>

A major point to note about this implementation is that it uses data binding between the list of key/value pairs shown on the web page and the list updated from the JavaScript. When the call to me.pushObject(t) is made, this adds a new object to the configController list and it is automatically shown on the page. The same happens when we delete key/value pairs - we call out to Redis to actually delete it, and then delete it from the configController. The display is always automatically updated.

References