All of this complex front end framework stuff I really don't see that it is necessary. You can write basically the most important part of the framework into a very small coffeescript file.
Ok now let's try to write a Todo List app. We'll have a TodoListView that shows a set of TodoViews. The TodoListView will need to initialize instances of TodoView for each item in the list, and react to model change events to know when to create or destroy new child views, so somewhere we'll need a map from model id to TodoItem view to do the book-keeping and cleanup. The child views will be displayed in order based on one of the model attributes, so whenever that attribute changes on a model, we'll need to find the relevant views and manually reorder them in the dom. And what happens when something in the todo item changes: do we re-render the whole thing (don't double-attach event listeners!) or selectively change individual parts of the dom?
If you've built large-ish things manually or with Backbone, as I have, this kind of thing is about 80% of your code. Just doing bookkeeping and manually futzing around to keep the dom in sync with your data.
Now compare with React, Angular, or Ember. Your list view just says: take all my todos, order them, and display each one in this way. It's the framework's job to deal with creating and destroying, reordering, and updating those views in order to keep the DOM in sync. This ends up cutting out lots of code while producing better results, since the framework is written by smart people and thoroughly tested, whereas ad-hoc list view implementations are generally either buggy or have memory leaks.
MyApp.CatManager =
init: ->
@container = $('#cats')
@collection = {}
add: (cat) ->
@collection[cat.data.id] = cat
@container.append cat.element
remove: (cat) ->
delete @collection[cat.data.id]
cat.element.remove()
all: ->
$.map @collection, (cat) -> cat
get: (id) ->
@collection[id]
arrange: ->
sorted = @all().sort (oa, ob) ->
a = ob.data.name
b = oa.data.name
if (a < b) then -1 else if (a > b) then 1 else 0
$.each sorted, (i, cat) =>
@container.append cat.element
true
Allows you to maintain full control over configuration and of what is going on. I have a question, Angular was built by very smart people at Google that is undeniable. But, does Google use Angular in their products?
I think that if the application needs to be sufficiently complex and the complexity maps to exactly what an existing framework does then you should use the framework that it fits.
This implementation will be incredibly slow for large lists. Every time any one of the elements moves, you will make N dom changes rather than the needed one or two. In an individual case, you can hand-write the faster version. But when you have multiple components like this interacting, knowing how to do a minimal change is not an easy task.
Unless you have experts writing these things by hand, using a framework is the quickest way to minimize performance problems and memory leaks.
Writing an observer class in easy, Managing the state of hundreds of them is not.
Now what if the user can change the cat's name by clicking on it and editing the div content,but cant give a cat a name already taken, because this cat is part of a collection of cats on that web page, which have the same editing features as Gary? Of course, cats are sorted and any change to one cat updates the sort order.
Suddenly your 39 line framework becomes worthless.
I am presuming that the application stores its state server side, if that is the case than this is not at all useless. Presumably you are sending the edited name to the server the server sends back the result of the edit. If the result of the edit was that the name was unavailable and therefore remains unchanged then this won't do anything:
gary.update.all jsonResult
Even if you aren't storing state server-side. In the update attr methods have name changing check the rest of your cats for an existing name.
https://gist.github.com/Kequc/11083050
Then your class: