While I actually totally agree with the confusion in the router, I want to explain what I see in Ember's MVC:
As far as I attempted to implement it in my app (https://github.com/thomasboyt/noted-app), it seemed simple enough. Models were data; all they contained was their properties and operations that controlled their properties.
I mainly used controllers as the "state" for parts of my app. In Ember, this doesn't even need to mean it's tied to a specific model type. For example, my Dropbox integration is handled within a controller that's bound to several separate views (in this case, those views included buttons that triggered syncing and modals that displayed the progress of syncing). There's no "Dropbox model," just other models that I'm using this controller to sync. Controllers are not simply an intermediary between models and views, they are an intermediary between state and views.
> I'm trying my best to reconcile this with the notion that a controller (classically speaking) is supposed to ... well control the view. Here, it's not doing that.
I think what the author was looking for in controllers is what's actually handled by, well, views. The view handles any user interaction, and then uses the controller to change the state of various bits (whether calling methods in the controller or simply updating properties on it).
To sum up: model is data, controller is state (including instance(s) of models), and the view is user interaction. Templates can bind to properties on any of these. Routes are what hook these components together depending on the page.
Seems reasonable, but the Ember team sees it differently... they put state in the router:
>Most of your controllers will be very small. Unlike other frameworks, where the state of your application is spread amongst many controllers, in Ember.js, we encapsulate that state in the router. This allows your controllers to be lightweight and focused on one thing.
In this case, the "state" that we're talking about is "what state are you in". In other words, the router manages high-level state ("I am looking at a post now"), and provides long-lived controllers with data reflecting that state. So even though there is information about the current state in the controller (and the view), the source of truth about the current high-level state is in the router.
"Application state", rather than "stateful vs stateless" state. The router specifies "I'm looking at a post now" and the controller specifies "Looking at a post means loading this particular Post model as well as these comment models"
I've found a more specific term than 'high-level' state to explain the router state is 'addressable state'. A single page web application has two types of state. Addressable state (which is stored in the Ember router) and then another form of state, let's call it non-addressable state which is stored in the controllers.
As an example you could have a web application that has multiple documents and inside each document there are panels that can be expanded and collapsed. As you switch between documents each document maintains its own version of which panels are expanded or collapsed.
In the Ember world the router would maintain which document was opened (addressable state) and the DocumentController would maintain which panels are opened (non-addressable state).
Nah, kidding. So they're totally right that there's a significant amount of state in the router, in that that's where you define which model and controller (and, depending on how fancy you get, what views and templates) to use on a given page. So those are essentially state.
The state that can make a controller fat is essentially state that's too important for a view but doesn't need to be universal to the page. For example, with my Dropbox controller, the controller has a state property that handles the various permutations of the state of syncing (i.e. it could be doing nothing, currently saving, done saving, failed saving, etc.). This state is set by the controller on the controller, and used by multiple views to determine things like which label a progress modal should have.
For example, if you had a controller representing a list, you might want to keep track of which item is selected on the controller. That way, if there are multiple views that can act on the currently selected item (for example - you might have a list item view that has a template that renders the item, and then a separate view that are buttons that trigger actions that act on the current item), they all have access to it.
Plus, I always think of state defined in a router as being limited to specific pages/routes, whereas some of my controllers are used on several different routes.
I think that that's exactly what it is. I've come to believe that every application needs a state machine that contains the shared logic and state that everything could possibly need to interact with.
> When talking routes, urls, and resources - that's a RESTful consideration and involves stateless state "stuff" (sidestepping the REST debate here). What is this concept doing in a desktop app?.
Ember is explicitly not about "desktop apps". That's actually why Ember broke off from Sproutcore. Ember is very opinionatedly focused on building web applications that are native to the web and stick to web conventions.
The best web applications still behave like the web is supposed to behave: they have shareable, bookmarkable URLs that allow the application's state to be recreated. This is a big reason Ember's router is different than the other examples you mentioned -- in Ember the router automatically handles a lot more of the state reconstruction stuff.
> The team has been rather clear that Ember is Desktop MVC, not web/server based
That's orthogonal to what I'm talking about. I agree that their use of the term "MVC" is much closer to the original meaning it had on the desktop (like in Cocoa) than the meaning in server-side frameworks like Rails.
But I'm not talking about what MVC means. I'm talking about what kind of applications Ember is intended to be used to build.
A flagship example would be Discourse, which is very deeply web-focused, and nothing like the way you would structure a desktop application.
I'd definitely say that Ember is more Desktop MVC than MVC2. True to it's Sproutcore/Cocoa roots, you are supposed to be able to wire up a lot of the application with the built-in controllers that don't have to be customized (or at least customized very little). Ember is trying to take that approach, make it more familiar to web developers, and add in some additional parts that are part of what makes the internet work (ie, routers for managing state/bookmarkable urls).
I come from Backbonejs background with which I have worked for about 1.5 years. So I feel quite comfortable with it.
I decided to try Emberjs - not for any other reason than trying to pick up something else and see how other JS framework approaches.
I gave full two-days worth of time into it. Initially I thought - "How different can it get?" Plus, I believe even if it's very foreign I'll just keep reading, googling, stackoverflowin', youtube-tutorialin' to get my head around.
I gave up though. Here's my hopefully constructive rant, though my views are probably not as deep as the OP's.
* Many of the posts on the net are outdated. I followed a few tutorials here and there, and then things didn't work, so I asked on Stackoverflow, then the answer I got was "Dude, your code is outdated". Sure this is probably similar thing for other frameworks - but I'm just sayin'
* Models - So there is Ember Object, which you can use as models, but you can also use Ember-data.js which is more "glorified" data. Documentation wasn't clear on the difference. Plus, Ember-data.js was quite hard to get started with. It didn't work well with other versions of Emberjs. I really had to dig in to find the right one to start off with. I ended up cloning a github repo of a tutorial that worked, because nothing else did.
* Documentation on "convention over configuration" - OK, so convention over conf. is fine. But the official documentation and many of the tutorials didn't explain what all the conventions there were. I went through a tutorial app, which only had Controller, but things just "worked", because the Emberjs builds all other things for you. Well I didn't know that! THE BEST INTRO EMBERJS VIDEO I found was this.
* But in the end, among all other things I wanted to do, I gave up, because the frustration was mounting up. I guess I can still persist through it. But I just finished AngularJS tutorial demo and in 2 hours, it makes sense to me.
The Ember teams has been planning for a sweep of all outdated information about Ember. We'll be updating SO questions and asking blog authors to add a disclaimer.
Ember Data is a completely optional component of Ember that seeks to bring ORM-like abilities to the client side. It's not as far along or as stable as core Ember. For what it's worth, you can easily just use jQuery.ajax and create Ember.Objects from the response. We probably do need better documentation in this area to make this clear. That said, it's not fair to count Ember Data as a point against Ember since no other framework has anything at all similar in scope.
Our overview documentation is lacking. This is something that we're actively working on improving. The hardest part for new developers coming to Ember is that the paradigms are very different than what they're used to. We believe that the paradigms are the correct ones, but we need to do a better job explaining them.
Without meaning to offend, I'm afraid I have to take issue with your points about Ember-Data.
Yes it's optional, and yes you can use jQuery.ajax or whatever, but in reality, it's not quite that simple.
The official guides in Ember default to assuming you're using Ember-Data (though they do at least mention it explicitly). This despite Ember-Data being far from production ready (as stated on the Github page) and far too slow for dealing with large quantities of data. At the same time, the conventions that are found in Ember-Data appear to be built in to core Ember (it says as much in the guides).
As far as Ember-Data not counting against Ember - it may be larger in scope than other client side data libraries (or the M part of other MVC frameworks or whatever) but the fact is that they are most definitely comparable, as it's the way that Ember gets stuff off the server, and saves it back to the server. Without Ember-Data, Ember has no built in way of doing that, which counts against it. With Ember-Data, well, it's not really ready yet, which also counts against it.
Ember is built to work with Ember Data out of the box, but it's trivial to make your own methods that fit with the conventions. I assume you're referring to the default `find` support in the router. All that Ember does is attempt to infer a class name and call `find(id)` on it if the `find` method exists. You can implement this method however you want, or even change your routes to call an entirely different method.
I totally get that it's different to what's in other frameworks (the router is similarly different), it's just that, for the most part, on the surface, it pretty much serves the same purpose (other than some relationship stuff that half works). That is, it's the same the same part of the framework, just with extra features. Oh, and with a whole load of undocumented coventions in it.
Btw, is there a diagram or something that shows how it's put together internally (I'm pretty comfortable with how to use it from an API perspective, but find myself having to dive into the source code fairly regularly)?
Unfortunately, no such diagram exists though it would certainly be useful. The lack of documentation is tied a lot to the instability of the Ember Data API, both of which are reasons why it hasn't had a formal release yet.
But, I really really think for a newbie (like me) to even find out that I can use jQuery.ajax to create Ember.Objects is confusing. The immediate questions following that would be
* How do I do that? Can I see an example? And where do I find a counter-example?
* Then why Ember Object (ok fine they provide cool ORM features, but when I'm starting, I just want to understand what/where things are)
I know a lot of people are raving about Emberjs, and personally it looks good and I really want to get into it, but really really really, I found it not-newbie friendly.
Creating an Ember Object is very simple: `Ember.Object.create(properties)`. If you want, you can subclass `Ember.Object` and then `create` an instance of your subclass. The main benefit to using `Ember.Object` is that you get convenience methods like `get` and `set` (instead of having to use `Ember.get` and `Ember.set`). You can also add computed properties and the like to subclasses. I think this is actually covered fairly well in the guides: http://emberjs.com/guides/object-model/classes-and-instances....
Creating an object instance with AJAX is as simple as just calling `create` with the data provided in the callback. However, you may want to create the object first, then update the object's properties in the AJAX callback. This is similar to how Ember Data handles things.
Also, `Ember.Object` has nothing to do with ORM. Ember Data addresses this with `DS.Model`.
Since Ember 1.0 isn't compatible with Ember x.0 you could save yourself a lot of that work by sticking to semantic versioning and just calling it 'Ember2'
I went through the same thing grandparent post did - a lot of old tutorials. I think it would be a good idea for Ember to make a complete break and to call this 1.0 release something else.
Semantic versioning states everything inthe public API should be considered unstable and changing until the major version is 1.
So whatever code samples are out there on blogs and SO were from the initial days of the API when it was changing a lot. I am with you and have been going through the pain of weeding out examples from the web that works with the latest version on GitHub. There were many methods that weren't even available in the current API.
Given the paradigm shifts with Router and the Controller, maybe what the Ember team needs to do now is to stop doing everything else and finish up on the documentation for their 1.0.0-rc.1 release before it is finalized to 1.0.0
I've never used EmberJS and am not familiar with any of the front-end JavaScript frameworks, but I don't get what's confusing.
It looks like instead of the controller pushing data to the view, the view asks the controller for data (which it might proxy to the model).
This makes sense with a long-running controller, right? On the web both the controller and view are ephemeral -- they last for just that one request -- but if the controller is running continuously then it needs to reflect changes in the models as they happen. The model(s) the controller references can change without the view changing its reference to the controller.
Without something like this the view would render stale data. I'm assuming this is why we have a controller.model, to add that layer of indirection.
What am I missing? How is this more complicated making the controller<->view relationship pull instead of push?
The controller is the data. The model is grafted onto it for convenience. This ties the view to the model to the controller which is sort of orthogonal to "separation of concerns". In my opinion at least.
That's not how I'm seeing it. The controller has data, some of which might be from the model. The view shouldn't care whether the data came from a model or not. It would be coupling if the view did care.
The view asks the controller for data. The controller might delegate that question to the model. The view shouldn't care whether the data was delegated or not; it should just get a response from the controller.
Seems like textbook object-oriented design. Otherwise how will the views update automatically when the models change? The views shouldn't know what models it needs. In fact, it seems they shouldn't know that models are a thing at all. It's just data from the controller.
This is actually where I think Ember does better than the Angular sample provided. Ember controllers hold the "data" in a "content" field on the controller (proxied). Any model can be placed there. If you do add a "people" field to the controller (as in the sample) I'd argue that does what you're describing here as "bad" because it's specifying information in the view about the model.
Great explanation. I'm not sure why (or if) ember states it so clearly.
A view calling controller.model.property is MORE tightly coupled than controller.property. The controller is tied to the view and the model as it's supposed to be. The view is not tied to the model.
No, it's not. Because a single controller over its lifetime can be bound to many different models.
The controller is glue. It brings together whichever model is appropriate at the moment with whatever view is appropriate at the moment, and makes decisions about when to change those things.
The controller is responsible for rendering the view when the data changes. It does graft the model data - and any other data you want renderable into the view. I wouldn't characterize it as "the data" however.
@rob: The controller should be the data as far as the view is concerned. Otherwise the view knows too much and the controller can't re-proxy a different model.
Knows too much about what? The view lives to present the data to the user - that's all it should know. The fact that the controller is the data is a design problem.
The data could be coming from multiple places and sources, only some of which are "models." This is true in Rails, too.
For the sanity of the view, the controller is the single point where it can get the data. It shouldn't know the nitty gritty details about where it came from, whether it's a "model," or anything else. The view is just, "Gimme the data, controller! Gimme!"
This principle is just as valid in Ember as it is in Rails. The only difference I see is that because the controller and view have to live forever, so to speak, it makes more sense for the view to pull data from the controller rather than have the controller push data to the view.
Maybe think about it this way. How is this any different than rails, really? In Rails you set goddamn instance variables in your controller actions. The view and controller are straight-up sharing state.
How is that less coupled?
This would be like the controller exposing getting and setter methods and instead of typing
<% @users.each do |user| %>
<li><%= user.name %></li>
<% end %>
you'd type
<% controller.users.each do |user| %>
<li><%= user.name %></li>
<% end %>
It seems like Ember does some "nice things" to handle the common cases and that there are additional assumptions, like maybe one model per controller (not sure I understand that), but there you go.
Ember seems less coupled all around than Rails and because of its long-running nature needs the view to poll the controller.
As mentioned above, the proxied model data is actually stored in a controller's "content" field. So that snippet is actually just shorthand for {{#each controller.content}} {{/each}}
It's not quite a shorthand as the controller can have properties of its own as well. However, the general understanding is correct, the controller proxies to the content. The controller is not the data, but it acts like it.
> The downside to this approach is that your HTML is "compromised", if you will, and many developers don't like that. My thought is that it's already compromised using Handlebars so what's the difference here? Personally I have no issue using the ng-* directives. Some people do, and I respect that.
I'm a bit off-topic, but you don't need to "compromise" your HTML with AngularJS, you can place "data-" in front of your attributes and you're HTML-compliant again :).
When I hear this argument I believe the concern is not the syntax of the binding with respect to the HTML spec, but rather the declaration of bindings in HTML at all. So the issue is not "ng-click" vs. "data-ng-click", but that "ng-click" in any form is no different than the pre-JS MVC horrors of onclick="mutateGlobalStateAndPerformIO()"; which is precisely the barbaric approach we thought we were vanquishing. I think that some people prefer to see bindings sprinkled on the DOM via code, as part of the bootstrapping process. I haven't used Backbone for a year but I'm pretty sure it is a strong proponent of "let nothing live in the DOM" school of thought. I don't subscribe to that, by the way, but that's the argument.
In Angular HTML is the view so that's where ng-click and friends go, while other MVC frameworks have view js files. I know people like to be 'unobtrusive' but many JS MVC apps would be useless without JS so there's nothing to fall back to (other than a plz turn on JS message).
I dislike data binding with a vengeance. From Windows Forms, to Web Forms, to WPF, to Swing, to QT QML, to AngularJS. I don't think this pattern will ever work for me.
What happens when you want to add a second, unrelated, thing? Just stick it on the end in the onclick? Create a new function called doTwoThings()? This is one of the reasons I prefer using an observer pattern over MVC.
That doesn't really happen though - also, Ng-click is a specific directive you can choose not to use.
A more general argument is that any behaviour specified in markup is bad. I'd counter that by saying that it's already there in HTML. Input boxes for example have behaviour intrinsic to their being. So angular let's you create a (for example) richtext tag. You attach behaviour to that tag, say on click. In the HTML it's as clean as <richtext>. Within the directive you can make it behave as you please.
I think that people see the shortcut directives used in angular (eg Ng-click) and the purists shout "unclean"! The reality is that You can do things a slightly longer way and end up with something thy looks a lot like the observer pattern.
Nothing, but some feel rather strongly averse to it, and plainly view this as Angular's self-evident fatal flaw. As I said I do not subscribe to this line of thinking. My allusion to the horror and barbarism of the pre-JS MVC was merely a jape.
Absolutely true - I should add that in. I think people look at that, however, and don't like functionality etc. shoved into the DOM. But your point stands.
Really nice constructive writeup (as always by Rob), and I think it should be addressed by some better EmberJS docs and tutorials. They do a good job explaining the "what", but it could probably use more "why".
It took me a while as well to figure out why controllers proxied to models. However it started to make a lot of sense in when building an app, since the controllers are there to stay around, and the models are swappable.
Having the option to easily swap out a model at the controller level is worth the extra layer abstraction. That and the ability to add additional UI specific properties on the controller that don't necessarily belong in the model (since they don't need to be persisted).
I think the problem is MVC itself is a confused mess. It means whatever each person wants it to mean, since it's too easy to make up a bunch of reasonable sounding argumentation for whatever you want to do if you use the words model, view, and controller a lot.
This is the comment I agree with most. Replace a solution defined as a "design pattern" with one defined as a data structure and you get a lot more clarity. The problem MVC solves can be recomposed as "synchronization of concurrent, related, mutable data structures." The relations are definable as a DAG for each direction; the synchronization process with a cyclical graph.
I feel that as with many things in Computer Science, the original MVC-stuff is regrettably "under-read"[1] by a lot people. I highly recommend having a look at the various links on:
for those that haven't read what the original model-view-controller-user idea was all about. It makes more sense from a Smalltalk/Self/Object-C/Message-passing style of object orientation ("true object orientation") than from java -- in this sense it should be a good fit for javascript as well -- but unfortunately java/c++ style object orientation (really "class-inheritance orientation") have bastardized MVC to mean something subtly different (I am not quite sure what, exactly, but I don't think I'm the only one...).
That, coupled with the fact that MVC (the classic, desktop MVC) seems shoehorned in webapps, makes me weary when frameworks tout their MVCness before stating their distinctive features.
BTW, I'm much more adept of removing the controller and going to a tightly coupled stack of view-model with the use of the observer pattern where needed. Controllers remind me of that extra indirection that seems useful in design but is never really used and is thus just unnecessary complexity.
> I think the problem is MVC itself is a confused mess.
I tried to get to the core idea, and I think it is to separate things as much as possible, and minimize interconnections, so as to keep complexity down.
In practice it means to create components (objects) that keep their guts hidden and offer an official "API" to use them.
This might seem far from MVC, but what is the purpose of MVC if not to protect us from the exponential complexity black hole?
In the past I've been working on enterprise application suites for the desktop. The kind of monstrous applications that run on electronics manufacturing floors.
Such a typical application has a shell, modules, inter-module communication, dynamic module loading, plugins, and much much more.
One can think of it as Eclipse with its ecosystem.
To build such a system on the Enterprise with its typical NIH (not invented here) paranoid attitude was VERY hard.
I had to reinvent a lot of wheels.
On the Web, I've used backbone for a long time now, since almost the time it was out. I saw the same problems building complex applications with it (that backbone-marionette amends to a great deal). For a larger project, I evaluated Angular. Had very strong negative feelings about it.
Then I tried Ember. It took me a long time to "get" it. The only thing that kept me motivated is knowing that Yehuda, Tom and Trek and other capable people are contributing on it. I kept fighting through the outdated tutorials, the outdated videos, and even the peepcode video was embarrassingly confusing to me at some point.
But then it hit me. Ember and its infrastructure, the way its MVC is rigged, was very similar to what I was building from scratch on the desktop many years ago. It truly IS the one framework that "gets" desktop, or client-side, applications.
The causer of my confusion was that I didn't completely let go of the "Web-think" for building application. I was stuck at either server-side MVC (MVP), or bare-bones frameworks such as Backbone.
It's been just too long out of the real complex desktop game for me, to realize what that I'm looking at is a proper MVC framework.
So for me, Ember ended up as being great - it still takes me back to the way I was building desktop applications, and I'm sure it will become even better and better.
To understand it, you need to cold-boot your thoughts into that classic desktop MVC place; and if you were never in it, I think Ember is an excellent way to get into it as opposed to other frameworks.
Though, I understand the pain of coming from a server-side MVC architecture, I found it refreshing that Ember.js takes the "desktop" MVC approach. Our web apps are now living on the client, acting like desktop apps. Most people struggle with this reverse at first, but can conceptually catch on if shown the way. I think what really needs to happen is a good screencast or two walking through these concepts. I'm interested in putting something together and will when I have the time.
There seems to be some very positive buzz around this screencast mentioned both in the OP's blog and around HN in general: https://peepcode.com/products/emberjs . I found it particularly instructive but found that it only scratched the surface of this new framework. At least, it scratched enough off the top that I feel comfortable rooting through source and API documentation to figure out the rest. YMMV, of course.
i felt it did very well as an introduction. I think a deep dive into ember-data would be great for those who have been traditionally server side devs now getting into more of the client side stuff.
While there is quite a deal of information on integrating ember-data with rails, there is much less on integrating it with other server-side MVC/REST frameworks.
This means that using it with another framework often means modifying that interaction pattern to be more like how rails views ajax, complete with the root objects ({"model":{}}).
This may more accurately apply to the REST driver in ember-data, but that is quite tightly coupled with the rest of it.
As far as the root objects are concerned, I've always been a fan of that part of Rails. Not to say that it cannot be easily gotten rid of with something like this (for ActiveResource)...
ActiveResource::Base.include_root_in_json = false
Or, like in my example app, with this (for ActiveModelSerializers)...
I tried Emberjs and Angularjs recently, as both framework offered two-way binding between view & model, at client side.
Angularjs was easy to pickup and I have completed what I wanted to do in about half a day, except one issue, angularjs template rendering is DOM driven. I wanted server-side templates, hence I have to boot phantomjs at server-side. I didn't quite like booting phantomjs for server-side templates.
Since Emberjs offered, handlebar based templates, I was happy that I could render my templates at server-side. So tried emberjs, it took about 3 days, to get it done. Many out dated tutorials & documents spread across internet about older versions of Emberjs. Documentation at emberjs.com is minimal and not helpful. I started looking at source code of discourse.org and try to understand how they used ember.
I felt the power of emberjs when I needed complete control of context and rendering of nested templates. It was real beauty.
Not only SEO. If you need to build a webapp that is also a web page (eg: blog, wiki, cms) -- you want a rich client, but also relatively plain pages -- and ideally you want to share code/templates where it makes sense.
Also to improve "bootup time", from request to usable: server-rendered templates can be cached, can provide at least visible content before javascript even has to run and can use beefy servers & the like. At that point the client "only" has to do the events binding wiring and it's done.
I'm by no means an "expert" but I shared the same struggles and after 2 weeks of trying to build a complex app I gave up.
I switched to Angular (which I also had never used before) and got the same app up and running in a couple days with even more functionality because I was able to hash lots of the trickier "outside-the-box" functionality that I could not for the life of me get working in Ember.
That being said I really like Ember's syntax, Handlebars integration, core values (performance & stability specifically) and have the utmost respect for its creators. I'm hoping since it hit 1.0 that lots of new sample apps, blog posts and SO-type Q&A resources will start showing up and actually stay relevant for more than a month.
Think of Ember controllers as proxies, or pointers if you will.
The idea is you can have a commentsController instance, and when you switch to a different post, the view(s) bound to it will automatically pick up the new comments array that is swapped out on behind the controller.
Routing is just rewiring the pointers on your controllers and getting the right views up on the page.
Yes, I too agree EmberJS always a confusing library, Following are my resaons.
1)They say it follows MVC. Its actually MVC but MVP, if you look closely at the implementation.
2)Controller job is not precisely defined.
Example: Even the data validations are done at controller level not a model level
So i switched to Backbone.js, which is very flexible library with tons of plugins that can be used when needed.
Since implementation of UI is different from requirement to another requirement. I feel EmberJS doesn't satisfy this, which leads to people using Backbone.js.
Regarding AngularJS, please use it only if you are new javascript and prefer learning Angular Javascript (which is not javascript by the way) :)
Regarding AngularJS, please use it only if you are new javascript and prefer learning Angular Javascript (which is not javascript by the way) :)
I am not sure you "know" javascript. If you are saying that there is an Angular version of javascript then you are terribly mistaken. Angular is probably one of the only mainstream framework that stays true to javascript. All other frameworks ( Backbone, Ember etc.. ) are the ones that actually mould javascript into an OOP language. I would say that Angular uses the prototype chain ( you know javascript is a prototypical language right? ) the best. The whole scope object inherits prototypicaly while in all other frameworks we create an illusion of OOP. Someone correct me if I am wrong here.
Just for clarity, I believe that when you write Angular code you are writing the purest form of javascript. Because thats what you are writing there. Just plain javascript. There is no constructs imposed by the framework at all. This is probably why most people think "Angular's javascript" is not javascript. They have been always fed layers on top of javascript because "javascript is somehow not optimal, not right" and it has to be "changed" and "corrected" . OOP is shoved down the throat. This is probably gone on to the extent that when someone actually writes in pure javascript it starts looking like a foreign language !!
Before berating other people's knowledge, you should probably make sure that what you are saying is infallible. So with that I ask you:
Do you realise that JS is an object oriented language? Prototypes are a means for inheritance (i.e. reuse of code), just as classes are in more traditional languages - it does not mean JS is not OO.
My interpretation of the GP comment is that he means angular to JS is like jQuery to JS, it's effectively a DSL that you have to learn in itself. Someone once said "people don't write javascript anymore, they write jQuery". That's what I think he meant
Uh, you were the one who suggested JS wasn't OOP-oriented. It's all JS to me. jQuery is just a function that's spits out adapter/decorator objects. Just as Angular, Knockout, Backbone, Ember, etc... are all just bloatworks that miss one critical point. We already had the V and the C pretty well covered. They're throwing a big veil of abstraction over one that was already there and worked fine. It's like webforms all over again only this time we're trying to pretend the client-side isn't already what it is rather than not there at all. And while yes, IMO, we should think of web apps as two separate apps, the client-side's concerns are localized enough that it's kind of silly to try and apply MVC to it (not that what any of this stuff does can really be called MVC or MV-whatever anyway). What is it with modern developers wanting frameworks to be the answer before they understood the question in the question in the first place? How do you even write this stuff without starting to feel a lot silly about the fact that you're just duplicating effort? Because at some point they all have to bind with the mechanisms already in place to bind to their own bindings and that's just stupid.
Are you replying to the correct person? I quite clearly stated JS was OO, whilst the GP clearly says that MV* frameworks "create an illusion of OOP".
If you're not convinced of the benefits of MV* frameworks on the client, please write a complex client-side app with vanilla JS and share what you learnt.
I'm being sincere there - I've tried, and I quickly started drowning in sea of boiler plate code I'd rather not have to write. Not that it's not fun to write some of that stuff, but I'd rather be delivering value. And what happens when I create a second app? Hmm seems there's lot of similar boiler plate stuff, why don't I just abstract that into a framewo.. oh wait
Did you actually read what I wrote? I do agree I missed writing "classical" OOP in there, but I guess I assume wrong when I think that people can fill in the blanks. Here is the jist of what I mentioned earlier - "Most frameworks provide abstractions over javascript that create the illusion of classical OOP".Angular doesnt! .
I am talking about prototypes and the prototype chain there? You still think I am just throwing keywords in the air, in that previous sentence and dont understand javascript? You still think I am just writing crap there because ( fill in the blank! )?
> Regarding AngularJS, please use it only if you are new javascript and prefer learning Angular Javascript
I'm not sure that's very fair to AngularJS. I gave up on Backbone and Ember because they had too many features, then later I was comparing JavaScript MVC patterns and stumbled across AngularJS which just made sense.
If what you mean by 'prefer learning Angular' is you have to understand $scope and $resource, $http etc, that's true of using anyone else's code, plus it's not exactly a massive library!
I'm genuinely curious why you think Angular _isn't_ Javascript?
Yes that's exactly. you got it right,If you are JS developer, you still need to learn about "understand $scope and $resource, $http etc," features.
If you feel my comment about Angular is completely Unfair, I agree with you and will delete it. But here is my argument.
Why Angular is not Javascript:
1) The code written in Angular javascript gets compiled into javascript.
2) Tough to extend Angular and implement features that are not supported by Angular. Please Try adding new features on your own, then you will feel the pain.
3) Mixing bindings between the markup and script is not a good way to add bindings. Bindings should not be mixed with Markup (Unobtrusive JavaScript).
4) I felt Google is doing the same mistake they did with "GWT". They are not thinking in terms of issues faced by other JS developers, That is why jQuery is still pretty popular (Plugin based approach)
While developing client side app, each requirement is completely different and you really don't need a framework to address all this. But you need libraries like Backbone, jQuery ...etc as per the requirement and backed by open source . This is why, i love Backbone,jQuery ..etc
I worked on 4 applications with each having its own simplicity and complexity that uses Backbone. Never faced any issues, Community is very supportive.
If you have done R&D on JS MVC and like Angular than Backbone JS (Ember JS always confuses me too), Please continue with your work. Because there is always a nicer way of doing things in Client side :).
I've only looked at it but I know people who are into it and I'm not aware of Angular compiling anything. There's this crap they do with the "DOM-compiling" or whatever but that has little to do with rewriting JS or compiling AFAIK. That's just Google engineers wanting to feel like they have their big boy pants on when they talk about their JS framework.
Yeah, I know this. You wouldn't be able to step through your code in browser dev tools otherwise.
The DOM manipulation stuff is one of the features which sold me on Angular. I love the idea that everything renders itself then responds to a single redraw event fired on the DOM so that reflow happens once rather than the hideous way many people use jQuery to do things like:
var div = $('div').appendTo('.home');
var ul = $('ul').appendTo(div);
$('li').appendTo(ul);
> If you feel my comment about Angular is completely Unfair, I agree with you and will delete it. But here is my argument.
I said a little, not completely, but we're all entitled to our opinions, that's why we're here :)
> 1) The code written in Angular javascript gets compiled into javascript.
I don't fully understand this - although I have only been using Angular for a few months - are you talking about my code in my controllers, views, services etc? because it doesn't seem to compile it and I can step through in browser developer tools. Or are you talking about the directives?
> 2) Tough to extend Angular and implement features that are not supported by Angular. Please Try adding new features on your own, then you will feel the pain.
Again, perhaps it's my use case, I haven't tried to add features to AngularJS but treated it as a dumb framework, adding my own libraries to perform localstorage, offline/online sync, custom view transitions etc. What have you had difficulty implementing?
> 3) Mixing bindings between the markup and script is not a good way to add bindings. Bindings should not be mixed with Markup (Unobtrusive JavaScript).
I agree with you here, however unless you're entirely building the DOM from scratch in JavaScript, you're probably going to work with HTML/CSS templating developers. I feel Angular gets the balance right of extending the templates with directives while not making the HTML generation completely opaque.
> 4) I felt Google is doing the same mistake they did with "GWT". They are not thinking in terms of issues faced by other JS developers, That is why jQuery is still pretty popular (Plugin based approach)
Maybe they are, however jQuery solved the problem of writing one set of JavaScript code which ran on all browsers, even though they all used different syntax (remember the old XHR JS?).
I see a lot of people use jQuery in a hamfisted attempt to modify the DOM without considering Layout/Reflow cycles and then they complain that their pages are clunky and slow to use.
I have an issue with client-side template engines which use handlebars/some other syntax because it's yet another templating engine that HTML developers have to learn, rather than just ... using HTML, which is already a standard.
> I worked on 4 applications with each having its own simplicity and complexity that uses Backbone. Never faced any issues, Community is very supportive.
I think that's great! It would be a very boring world if we were all the same.
> If you have done R&D on JS MVC and like Angular than Backbone JS (Ember JS always confuses me too), Please continue with your work. Because there is always a nicer way of doing things in Client side :).
I swore off writing frameworks a long time ago! :) There are a lot of people much cleverer than I, working on them, plus I much prefer working in the UI/DB area.
Looks good. I think you may have a character encoding issue on one of the questions (it was the rearrange the letters one) I was getting ? ? letters in Chrome on my Mac (UK).
> Please share your toughts, Why you prefer Backbone JS over Angular JS ? It will be very helpful.
Today, I prefer Angular to all the other frameworks, but like I said I don't _want_ a massive library, I just want the routings/DOM manipulation to be handled for me and I can do the rest!
Having said that, if a new project came in tomorrow which was a perfect fit for what Backbone or Batman does, I would go for it. The right tool for the right job!
If Angular was to become a massive framework, I would probably ditch it or just use the parts I need.
I enjoy these discussions, especially when other people know more about a different library than I.
i've been using ember for the past three months in a fairly complex project and i'm very happy with it ; a platform that builds business web apps dynamically for devices (20+ pages,250+ fields per app with validations, calculated fields, conditional flows etc , rendering/theming in jqm -> packaged with phonegap) and client web browsers (render/theme in bootstrap),the backend is in java. So, i certainly don't feel the same way for emberjs as the writer.
I had decided to build the frontend in a js mvc framework and the candidates were backbone, emberjs (pre version), angularjs. Read about them and gave backbone a try, however from the documentation only emberjs approach felt better maybe because of a similar in-house development java framework that we work on. So i tried to give emberjs a try at the same time, due to the tight deadlines. I dropped backbone, and spent more time on emberjs because everything simply worked and fitted together nicely. All these binding mechanisms are great and actually work :) . Haven't tried angularjs.
The system now works with emberjs (pre and rc) with a nice layered architecture and separate independent business logic modules.
My advice is to read the documentation carefully and choose what fits better to your needs and coding styles.
Your examples are incorrect. The Route's model is set as the content of the controller, so all you need to say is #each item in content. Your model is set as the "content" of your controller, so your model is not "nowhere to be found"
You should use {{#each item in controller}}, otherwise you won't get things like sorting of filtering right. Yes, content is an underlying array, but controller may present it differently (filter out, sort, paginate etc.).
The examples provided to describe the difference between controllers in Ember and Angular do not appear to be different to me at all. In fact I'd argue that they are identical. It feels to me as though the author is wanting them to be different because maybe it's a style preference from the templating perspective?
The examples were to show how $scope is used in Angular vs direct use of the Controller/Model proxy in Ember. This makes a bit more sense to me, personally.
Interesting - didn't know this. $scope is injected by Angular and available to the view - is this the same thing? I didn't think Ember had a DI aspect to it.
That's the hunch I had reading this (as someone with no EmberJS experience).
To digress a little, it's not much different than the terminology confusion in Backbone, where:
- Router(s) work as front controllers,
- templates (along with the browser's DOM) as views, and
- Views as presenters (from the MVP pattern).
Models are flavored with the Active Record pattern. Presenters and views are tightly coupled.
MVC and MVP coexist because the controllers respond to navigational input (mapping to model-presenter pairs) and the presenters respond to page-specific input (mapping to model manipulations and, possibly, server calls).
We have applied EmberJS to a fairly complex application backed by Rails backend. We had to deal with complex JSONs delivered by backend which were schemaless MongoDB documents. At lot many places we had non RESTful Rails controllers. So when we started with EmberJS we had a worry the documentation was not proper, there were very few reference projects. After a few weeks of thrill and steep learning we settled on with things. We have applied a lot of functionalities offered by Ember to our code. Migrated from router from old to new api of pre 4. But we feel in our team it was right thing to apply Ember. The way overall MVC imposes structured programming, the way HTML is seperated from JS, the way ember data can have serializer and adapter customized, two way bindings all of it had been useful. We struggled at few places with deep nested JSONs in hasMany/belongsTo relation in embedded JSONs. But doing workarounds were easy. We used fixtures to hasten development while backend was not yet ready. All in all we believe that we made a good choice to stick with Ember, though it looks difficult to comprehend on the start but thats also getting better with time.
I'm confused by all of these MVetc... libraries. We had routing behavior to content/views covered already. How is anything that does more than help isolate/manage data more than cruft in regards to having some sort of MVC-but-not-really-style-app on the client-side-web? IMO, it's all just pointless abstraction of the type that JS devs should have learned to avoid from observing server-side fail over the years. What really blows my mind is the number of these frameworks that embed pointless behavior dependencies directly in the HTML and act like they're doing us a favor. That's awesome, now we're back to changing things in multiple places to make adjustments to our apps that used to happen in one place following basic "duh" best practices that the authors of these frameworks don't appear to have ever understood properly. HTML is the router you saps! Hell, how about we add pointless-in-a-language-with-first-class-function IOC fail, config files and pointless dependency management as well? Wait WHAT!? ARE YOU !@#$ING SERIOUS!?
I think the way controllers work here is similar to Ruby on Rails? It confused me in Rails at first (coming from the Java world), but I think it is essentially just a hack to allow for "easier" passing of data to the view (the controller gets exposed to the view). So instead of scope.whatever = "hello world" you can write this.whatever = "hello world" (OK not really shorter, but something like that).
That usage of Controllers is not part of the MVC pattern, I'd say. It's just a recycling of the controller instance - not forbidden, just confusing if you wonder what it has to do with MVC.
Actually it's also the RoR way to have short lived controllers (a controller is instantiated for every request), other frameworks use one static controller instance instead.
The Angular example is a bit incorrect... when you do an ng-repeat, you're going to do like ng-repeat="person in people" and then each template item will be like {{person.name}} as opposed to just {{name}}.
Just a little clarity in the code. Thanks for the writeup!
> Ember is explicitly not about "desktop apps". That's actually why Ember broke off from Sproutcore. Ember is very opinionatedly focused on building web applications that are native to the web and stick to web conventions.
This may be the issue. I think most of us never really wanted to build web applications, but we were forced to do so due to browser and framework limitations.
We really just wanted to build the best damn desktop app possible that just happened to be deployed in a browser via the Web. This might explain our confusion and disappointment when client side frameworks don't deliver on that desire.
Most of whom? I came up in JS on the client-side. Nothing has been more frustrating over the years than watching all of the inflexible bloat and tightly coupled BS people have been piling on to the client-side in order to pretend it was something that it is not. Web forms sucked ass. Everything Java tried to do to pretend the client-side wasn't there has left massive legacy potholes all over the web. Just deal with the thing as it is already and learn something new. You're a programmer for chrissakes. I might indulge in writing OS apps with webkit but I don't try to add a server to the process if it's just a local desktop app in order to make it more like what I'm used to. HTML, CSS and JS properly applied are doing 4/5ths of what these frameworks are pointlessly reinventing. All you have to do is learn them properly. The rest, keeping data loosely coupled, is basic 'duh' OOP. All the stuff that's already there works surprisingly well if you actually give it a chance. Or have you not noticed that web technology solutions are spreading like wildfire into other domains or that we can implement and modify GUIs using client-side-web-technology a lot faster than desktop OS UI developers have ever been able to? FFS, they don't deliver on that desire because it's proven time and time again to be a complete waste of time to try to.
Are you implying that Ember doesn't deliver on this desire to build desktop class applications in the browser? If so, can you explain where it falls short?
Instead of controlling the view directly from the controller, the view uses the controller object (proxy to model) in any way it wants allowing you to change the view without changing the controller and same with the controller. I think the issue you are facing is thinking that you are tightly coupled to the controller by using the controller object, depending on what you think about how much coupling is too much coupling you can argue that just using one object might really be decoupling. I'm not sure if I was able to get my point across.
Well, I don't know EmberJS but for the handlebars code you showed, seems like the controller is somewhat more like a ViewModel (MVVM pattern), maybe learning KnockoutJS first would help a bit?
Rob has done knockout, and that's pretty unrelated I feel. I've spent a lot of time doing Knockout and a fair amount of time in Angular and Backbone, and personally I sort of agree with what rob is saying. I feel like they have taken MVC and just loosely applied it in Ember, because they have Models Views and Controllers. I see and understand where his confusion is coming from. I probably also haven't spent enough time with Ember to get it, but I also don't feel like I want to.
I have been into MVC frameworks for 4-5 months now...mostly used BackBoneJS before switching to EmberJS..conceptually I did felt EmberJS very tough in the beginning..i was worried whether i made the right choice in using EmberJS for my product..but now with the latest 1.0rc2, its so easy in development..routing has been improved very much..Binding is the awesome feature i liked and helps me thgh..an added advantage over BackBone...i cant say about angular..but am quiet happy with EmberJS...
Ember confuses me too. I've worked with many server and desktop MVC frameworks for almost 20 years. I'm familiar with MVC, it plays simple and easy, like rock-paper-scissors.
My problem with Ember is that it seems to be more like "rock-paper-scissors-lizard-spock but for us the rock punches through the paper and the scissors cut the rock like butter. And you can play without actually showing your hand". Confusing.
At first read, I thought your point about routing was really good - why not have route('about').template('aboutTemplate').controller('aboutController') - and then I realized this is all reapeating the same mumbo jumbo. This is all automatically matched up by the naming convention (which frustrates me too, but until I figure out a better way...)
The only reason is you are in love with AngularJS. I will find someone who really hates angularJS because if we have a lot of validation, it will become a messy of ng-*.
So no matter which framework we use, we should talk about real world project. Not simple usage that only exists in trying and testing.
Use the framework, you love and you will make it beautiful no matter what :D
At this point, you write a directive. Your directive should be watching your model and adjusting as appropriate, rather than trying to fit everything into the provided.
I have not used Ember, but you mention MVC, which immediately brings to mind Sencha. I have used Sencha a lot, and although I think it is mostly great, I do not like how they try to pidgeon-hole you into the MVC methodology, which just does not make sense in many contexts.
If you need help, want to suggest a modification, or otherwise need to interact with the author(s) of something you're using, it's nice to have friendly people to deal with, rather than assholes, all else being equal.
I just think the basic idea is to keep things as separate as possible, to keep complexity down. Just encapsulate things OOP-like, hide the guts, and provide a clean access API to them. That makes it manageable.
As far as I attempted to implement it in my app (https://github.com/thomasboyt/noted-app), it seemed simple enough. Models were data; all they contained was their properties and operations that controlled their properties.
I mainly used controllers as the "state" for parts of my app. In Ember, this doesn't even need to mean it's tied to a specific model type. For example, my Dropbox integration is handled within a controller that's bound to several separate views (in this case, those views included buttons that triggered syncing and modals that displayed the progress of syncing). There's no "Dropbox model," just other models that I'm using this controller to sync. Controllers are not simply an intermediary between models and views, they are an intermediary between state and views.
> I'm trying my best to reconcile this with the notion that a controller (classically speaking) is supposed to ... well control the view. Here, it's not doing that.
I think what the author was looking for in controllers is what's actually handled by, well, views. The view handles any user interaction, and then uses the controller to change the state of various bits (whether calling methods in the controller or simply updating properties on it).
To sum up: model is data, controller is state (including instance(s) of models), and the view is user interaction. Templates can bind to properties on any of these. Routes are what hook these components together depending on the page.