Distal
Inspired by EmberJS building a better view abstraction for BackboneJS, but not as overgrown as Ember.
Why Distal - or the Problem Statement
Backbone is pretty cool. I think it has done a good job of the Model/Collection/Sync approach to data. The challenge is that while the Backbone.View object is a good simple abstraction for a view as soon as you want to do something more involved. Either with a "layout" concept, or having collections just do the right thing on presentation you'll discover that you're writing a lot of boilerplate code.
For instance why is your render function something like - there are many varients out there::
render: function() {
this.collection.each(function(tweet) {
var view = new TweetView({ model : tweet });
this.$el.append(tweetView.render().el);
}, this);
return this;
}
Clearly we could just wrap render in a FizzleView which removes the render, but that's not quite the objective. Real goal is to get the View focused on events and handling of events not on rendering since 99.9% of the time that's really views with composite views.
Maybe I want something more like this:
<div><a class="add btn" href="add/{{ lid }}">Add New Item</a></div>
<!--
-- iterate over all the elements of App.data.gear
-->
{{#collection App.data.gear id="items"}}
<!--
-- display the item, attaching the App.ItemView object to the contained HTML
-- event handlers, or other helper functions
-->
{{#view App.ItemView model=this class="item-group" }}
<div><a data-toggle="collapse" data-target="#item-{{cid}}">{{ title }}</a></div>
<div id="item-{{cid}}" class="collapse">{{ description }}</div>
{{/view}}
{{/collection}}
So, now most of the rendering code and chained rendering code things compositing other View objects can now be left back in the HTML rather than putting everything in your ''render: function....''
Final Note: Why not EmberJS? Simple: This is about Backbone and Backbone style JavaScript, I don't want the whole system fixated on magic through "...Binding" or other things, it's goal is to be explicit and straightfoward to create Views which still look 99% like Backbone Views.
Examples
There are three sample apps currently built, which I'm using as a test bed for how to approach things.
-
Todo - Really a basic app, based on the EmberJS ToDo app trying to demonstrate good simple abstractions for how things can plug together
-
GithubViewer - Based on the Layoutmanager, while I'm not focusing on using layouts in my version it does try and give a good example of what an app might look like (uses RequireJS for parts).
-
Jobs - Based on the Backbone.Marioneete Jobs app, this is more an exploration on how to do layouts. As of this writing not 100% happy with what's there, but it's a framework to start from.
Test Server Usage
It's a python/tornado server, so you'll need python and tornado installed. Simple as:
./server.py
# By default it run on 9000, if you want you can say --port=NNNN for a different port
If you need tornado you should be able to do a pip install tornado
or easy_install tornado
, but if that fails, look http://www.tornadoweb.org/ for additonal help.
Example
Image a template that looked like this and some JavaScript that follows. Instead of doing the whole process of defining the template wiring it up doing a bunch of creation we can do something as simple as focus on what we want to accomplish.
From the index.html file
--
From the todo.js file
Todos.CreateTodoView = Backbone.Distal.TextField.extend({
events: {
'keydown' : 'create',
},
create: function(evt) {
if (evt.keyCode != 13)
return;
var value = this.$el.val();
if (value) {
Todos.todoList.create({ title: value });
this.$el.val('');
}
}
});
Documentation ToDo's
-
Document the {{#view ...}} and {{#collection ...}} constructor
-
document the base fields extends for Views
- itemView
- className
- template
- templateName
- other fields are passed throught
-
initialize
-
post_render
-
document the events
- pre_render
- post_render
-
document event based views
- event-sink= # where the event will be sent - clearly some other object
- event-data= # what data is in the trigger (default the view)
- distal-on= # "ACTION EVENT"
-
Layouts
- show
Credits
Some of these were inspiration, some were just learning and getting and idea of how to approach different problems with Backbone.
- EmberJS - http://emberjs.com/
- Backbone.Layout - https://github.com/tbranyen/backbone.layoutmanager
- Backbone.Marionette - https://github.com/derickbailey/backbone.marionette
- EmberJS Todo - http://emberjs.com/examples/todos/ - Sample EmberJS Todo Application
- Jobs App - https://github.com/stormabq/jobs - Michael Angerman's sample jobs app