

Agility.js - Javascript MVC for the "write less, do more" programmer - arturadib
http://agilityjs.com

======
JesseAldridge
I looked into using Backbone for my current project, and took a peek at
several other MVC libs as well. In the end I decided they all did way more
than I was looking for. I just wanted a simple way to separate my models from
the DOM. This project seems better than anything else I've seen, but still,
1000 loc seems like a whole lot.

Here's how I'm currently doing it:

    
    
        window.models = {}
        function json_to_model(json, parent_model) {
          // Create initial attrs.
          var id = '' + Math.round(Math.random() * 100000000000)
          var children = json.children
          delete json.children
          json['id'] = id;  json.is_expanded = true
          json.child_ids = [];  json.parent_id = null;
          if(parent_model) {
            json.parent_id = parent_model.get('id')
            var child_ids = parent_model.get('child_ids')
            child_ids.push(json.id)
            parent_model.set('child_ids', child_ids)
          }
    
          // Store models.  Recurse children.
          var new_model = {attrs:json}
          add_get_set(new_model)
          window.models[id] = new_model
          render_model(new_model)
          if(children) {
            for(var i = 0; i < children.length; i++)
              json_to_model(children[i], new_model)
          }
          return new_model
        }
    
        // Get and set.  Render on set.
        function add_get_set(model) {
          model.get = function(key){ return this.attrs[key] }
          model.set = function(key, val) {
            this.attrs[key] = val
            render_model(this)
            localStorage.setItem('models', JSON.stringify(window.models))
          }
        }
    

Now, that doesn't do much. But for prototyping a gui, it seems pretty good.
Less is more. I wonder how little code I can add to get it to work with a real
backend.

~~~
delambo
If this solves your problem, then you probably didn't need MVC in the first
place. But this doesn't necessarily decouple you from the DOM, and it sounds
like all of the code that works with these models is a bunch of jQuery
callbacks hooked into the DOM. Is that right?

If so, and your project is sizable, then an MVC, like backbone.js, could be
beneficial.

~~~
JesseAldridge
The code can work with the models without touching the DOM. You just access
the models via ids.

eg

    
    
        parent_model = window.models[foo_model.get('parent_id')]
        parent_model.set('text', 'foo text')
    

When you respond to a button click or whatever, then yeah, you use a jQuery
callback. The model id is stored in the DOM element (the view) which you
access with $(this). Whenever the model changes (via set), the render function
is automatically called. The render function is responsible for passing
attributes to a template which renders html. Then the render function sticks
the html wherever it's supposed to go. I think that's basically how all MVC
frameworks work under the hood.

------
timruffles
Looks like a nice mix of concepts you've seen in dojo/Backbone (very similar
#set #get ersatz message passing etc) with those in Knockout (two-way
model/view binding). The combined JS/CSS widget definitions make sense for
people writing components.

------
rushabh
This is really nice. The code of the demo app reads quite well - not only is
it small its quite readable... I was thinking of using backbone for my next
rewrite. Will have a serious look at this.

------
tommoor
Not liking all that html/js mixed together in every single example...

Each to their own! :-)

~~~
arturadib
Hi there, that's actually something I like about Agility, but I will soon add
support for HTML templates outside of JS objects.

PS: You can already skip in-object CSS.

~~~
bobbywilson0
I'm interested in your preference for HTML in JavaScript, what is your
rationale?

~~~
arturadib
First, I don't have to keep looking for ids/classes across multiple files when
I'm maintaining/modifying an object. This makes maintaining an object that
much easier.

Also, because Agility allows me to refer to the root element of a view as the
selector "&", I don't have to worry about maintaining that additional
id/class. This becomes especially useful when you have many MVC objects (as
most projects do), each with their own root element. Suddenly you have
eliminated dozens of unnecessary ids/classes.

------
stephth
The approach of mixing it all together - not just html/css/js, but also MVC -
but still clearly separate those semantically, is very interesting. Thanks for
sharing, @arturadib.

What flavors of server-side frameworks would go well with it?

~~~
arturadib
Thanks! I guess right now, given that the only persistence adapter provided is
RESTful, any server-side that speaks REST should play well (Rails, Node-
Express, etc).

Check out the The Wall demo code for a Node.js example:

<https://github.com/arturadib/thewall>

------
hippich
Nice lib for small apps. But for something bigger I would consider go for
Backbone - it have much more defined separation of models/controllers/views.

Although I like data-bind stuff - really neat!

~~~
arturadib
Hi there, thanks for your feedback!

I don't necessarily agree with that Backbone comment. Separation of M-V-C
(which Agility does too) is merely a fine-grained level of code organization,
and it doesn't help with a large code base with many different abstract
objects/components.

For example, as you can see from the following code (from our demo app The
Wall), the most significant aspect of code organization comes from a
separation of concepts - such as "error message", "posts", "profile",
"stream", etc - as separate objects:

[https://github.com/arturadib/thewall/blob/master/public/app....](https://github.com/arturadib/thewall/blob/master/public/app.js)

But again, Agility supports the more explicit syntax "model:{}", "view:{}",
"controller:{}", if that's what you think helps you with your large code base.

------
rmoriz
Artur, please stop spamming all backbone.js watchers on github. thanks

~~~
ibjhb
+1

------
alecperkins
Seems neat, and the ugly parts, like \ in the strings for the templates, could
be helped by CoffeeScript's syntax. I'm not wild about mixing markup and style
into scripts, but it does keep things nice and self-contained and could be
great for small projects.

On the other hand, I don't like getting an unsolicited message about the
project just because I'm watching Backbone.js on GitHub. I was mostly
indifferent to Agility.js before, now I have some dislike of it.

~~~
devth
Agreed. This is the second time this has happened to me in the last few
months. Using GitHub repo followers as a spam list is unacceptable and makes
me immediately dislike the project that the spammer is trying to make known.

------
nikcub
what is with all the markup and css in code? this will never work for any
project that requires designers. (ie. 95%+ of commercial projects)

------
arturadib
Don't forget to check out the demo app:

<http://thewall.agilityjs.com>

Thanks!

~~~
buster
How would you do i18n in agility.js?

------
josscrowcroft
Does seem very neat and I like the proposal except for the idea that all
JS/CSS/HTML are all contained in the same code... that to me seems like a
recipe for headaches down the line, even if it does speed up initial
development.

~~~
arturadib
Hey there, I think it's actually the other way around -- down the line, I will
appreciate the fact that all that stuff is right within the object I need to
work on.

There's no need to go around multiple HTML/CSS/JS files looking for the
ids/classes I need to maintain. It's all right there.

(I agree that the need for a backslash is annoying, but the tradeoff is
favorable in my opinion).

That being said, you don't _have_ to use in-object CSS, and very soon we'll be
relaxing the HTML requirement as well.

~~~
rufugee
I kind of like that idea as well, although the escaping is a little ugly. The
purist in me wishes I was always dealing with objects which knew how to
display themselves and behave. Then I'd simply be an object
arranger/orchestrator and life would be simple. What is wrong with this
approach really?

------
devmach
I liked agility.js. But why are you using REST by default ? I know it's "cool"
(= you can read this "other's use it" or "it's cacheable/more easy to
understand" etc.) but i really hate when someone dictates me something.

~~~
arturadib
Hey there, thanks for the feedback. I'm using REST b/c that's what I normally
use on the server side (also it's pretty popular).

Feel free to contribute your own adapter - it's really easy to create one! Get
in touch if you need help.

~~~
devmach
"persist" looks like easy to modify, i'll re-built it for my needs.

One suggestion : maybe not perfect but, for html templates you can do what
jQuery does: templates/html in <script> tag, user just gives the tag's id.
this way, one can store all templates in one file.

------
beck5
I am working in Node this summer and when I read "Javascript MCV" I thought
great a new server side framework. off topic yes, but blurring the lines
between server and client has unexpected repercussions.

~~~
pjscott
Where are the lines blurring? You've got a client and a server, and the two
are sitting on different machines, communicating only via HTTP requests. The
fact that they can be written in the same language is nothing too special; you
can do the same with desktop apps, and have been able to for ages.

If you could blur that browser-server line, I bet you could do some impressive
things. Bonus points if you manage to do impressive things without opening up
lots of security holes. :-)

~~~
beck5
its a small comment, I found my thought process quite interesting. If you want
to talk about really blurring then a framework which can easily and safely
share the same models on both the client and server would be very interesting.
(looking forward to seeing what batman.js is)

------
ErikRogneby
esc didn't work in the examples after interactions had occurred (or after
clicking inside the popup). I'm using firefox 5.

~~~
arturadib
thanks, I was aware of that. will open an issue.

