Structal is a new tool that mates the new client-side MVC frameworks (Spine and Backbone) with a back-end that provides automatic ajax data model Sync, and real-time JSON change feeds for each resource (SQL or NoSQL database table).

You can get the code at github, here’s a quick microblog Structal app:

class Posts extends Controller {
function init() {
// controller observes Post
// model's "create" event
Post::bind( 'create', 'addChange' );
}
function afterAction() {
// hook controller's "after"
// event to get/put/post/delete
trigger_after( strtolower($_SERVER['REQUEST_METHOD']) );
}
}

By extending Controller, we are enabling the back-end to provide automatic Model-sync via the built-in HTTP methods GET/PUT/POST/DELETE. The Spine.js or Backbone.js front-end Models will use Ajax to call the HTTP methods and pass data back and forth to sync the client Models with the server database.

Also, we need a server-side Model to go with the Controller, in index.php:


class Post extends Model {
static $id = array( 'type'=>'String', 'key'=>true );
static $author = array( 'type'=>'String' );
static $title = array( 'type'=>'String' );
}

And a client-side Model definition in app.js:


var Post = Spine.Model.sub();
Post.configure("Post", "author", "title");
Post.extend(Spine.Model.Ajax);

Now that the server-side is configured, we can create a pair of client-side Controllers with Spine, in the app.js file:

  var Posts = Spine.Controller.sub({
    init: function() {
      this.posts = new PostList({ el:$("#content") });
      this.routes({
        "/": function(params){
          this.posts.active(params);
          Post.fetch();
        }
      });
      this.navigate( '/' );
    }
  });
  var PostList = Spine.Controller.sub({
    events: {
      'click .create': 'create',
    },
    elements: {
      ".items": "items",
      "input[type=text]": "input"
    },
    init: function() {
      Post.bind( 'refresh change', this.proxy(this.render));
      //setInterval(this.poll, 5*1000);
      var el = this;
      $.get('tpl/posts/list.html', function(data) {
        el.html(Mustache.to_html(data,{}));
      });
    },
    render: function() {
      var el = this;
      $.get('tpl/posts/item.html', function(data) {
        $(".items").html('');
        posts = Post.all();
        for (p in posts)
          $(".items").prepend(Mustache.to_html(data,posts[p]));
      });
    },
    create: function() {
      item = Post.create({ author:'', title:this.input.val() });
      this.input.val('');
    }
  });
  return new Posts({el:$("body")});

Here's the template code for tpl/posts/list.html
<h1>Posts</h1>
<ul class="items"></ul>
<input type="text" id="title" />
<button>Create Post</button>

Categories: Web Apps

Related Posts

Web Apps

Build a lightning fast Web app with Spine

The way we program is always evolving, and Web apps are no exception. The surge in mobile-app development (iOS and Android) has reminded programmers about the beauty of pretty, well-funded commercial APIs. Developing apps for Read more…