Hacker News new | past | comments | ask | show | jobs | submit login
Agility.js - Javascript MVC for the "write less, do more" programmer (agilityjs.com)
110 points by arturadib on July 22, 2011 | hide | past | favorite | 34 comments



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.


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.


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.


Looked at backbone.js and thought the same thing - overkill for what I needed. I'm always thinking "how will I scale this to portable devices", and one important consideration is code size. Plus IMHO HTML/JavaScript/CSS is quite MVC to begin with (HTML/CSS being the View, JavaScript of course is Controller logic, and just don't make the mistake of using the DOM as your data storage and use JavaScript objects for the Model). Maybe it depends on the complexity of the app, and I'd definitely look at agility.js first if I needed something since it's lighter than backbone.js ...


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.


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.


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

Each to their own! :-)


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.


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


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.


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?


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


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


+1


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!


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....

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


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.


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.


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)


Don't forget to check out the demo app:

http://thewall.agilityjs.com

Thanks!


How would you do i18n in agility.js?


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.


That is actually one part I liked, especially the HTML.

For bigger projects I would do the development of different parts of the app in different JS files and have a server side script combine them when requested from a web browser.


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.


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?


If you use this with Coffeescript, you don't need the backslashes. :)


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.


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.


"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.


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.


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. :-)


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)


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


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




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: