I'm hoping someone can clear this up for our team. Why exactly are controllers singletons which don't get reset on navigation? In what situations is it better for them to not reset every time. I've heard "Controllers as singletons make perfect sense in any long-lived application" but non ember devs I've talked to were equally confused by this. Is this a design flaw that is being improved in the future or are we just looking at things the wrong way?
Hoping for a really clear answer I can take back to the team. Thanks everyone!
Not all controllers are singletons, most applications when they iterate over a collection will be creating instance controllers for each model. Ember dynamically creates a controller for you.
I use controllers to wrap all my model instances, eg editing a contact with multiple address models
Route based controllers are singletons because routes are singetons and normally persist for the life of the application once instantiated.
Ember doesn't need to tear down controllers and routes when transitioning between routes as the only thing that needs to change on rentering the route is the controllers content/model property.
It is trivial to clear the content of a controller on a route transition if you want to. I just recently answered a question on that which does that and additionally unloads models from the store as well:
https://stackoverflow.com/a/26695922/2238268
Singleton controllers can also be useful for managing other state in your application, perhaps gloabal session/authentication state.
So really Ember provides both singleton and instance controllers and they are both used heavily depending on the complexity of your business logic. I tend to keep my models fairly plain and put anything not route related in controllers. I do dirty tracking and undo/reversion in controllers as well as orchestration of persisting model changes in controllers. Aside from the route level controller I have a lot of instance controllers supporting views and implementing the update logic that can span many models.
I am currently developing a new system at work, using AngularJS. And the application currently has many Controllers, Services and Directives, and many dependencies.
The system has about 9 services, and most of them are reused in multiple controllers, so I injected them into the parent controller so they can be accessible by children controllers. Each service stores data used throughout the whole system.
However, as the development progresses, I find that it is getting harder and harder to manage, and in some cases, I have to do a bit of hack to be able to use the instance of a service at different places.
My question here is, instead of injecting all services into the main controller, should I instead instantiate them in the app.js file as global variables... but I don't really like the idea of having global variables, so besides doing this, would there be any alternative solution to this?
Services are singletons in Angular, so you should just inject them where ever you need them. It's not necessary to inject them in to an ancestor and propegate it down. Just inject it directly into the child as well. There is only one instance of the service regardless, so why not just make it easier that way?
Often times I will want to perform some action on every page of my web application or make some method available to all of my controllers. In the past with object oriented MVC frameworks I would have all of my controllers extend a root controller, placing everything I wanted done on every page in the constructor of that root controller. How would I accomplish something similar with sails.js / javascript?
I think your best option is to use a Sails "service" module (/api/services/MyService.js). Then you should be able to use it as MyService.function() from within your controllers.
See this GitHub question for more details.
Until now I was mainly using Struts 2, Spring, JQuery technology stack for building web applications. The point is, that mentioned stack uses server side MVC pattern. The main role of web browsers was limited to a request/response cycle (+ client side validation). Data retrieval, business logic, wiring and validation were mainly responsibilities of the server side.
I have few questions regarding AngularJS framework that were inspired by following quotes I've read:
From the AngularJS tutorial:
For Angular apps, we encourage the use of the Model-View-Controller
(MVC) design pattern to decouple the code and to separate concerns.
From the Wikipedia Model–view–controller:
Model–View–Controller (MVC) is an architecture that separates the
representation of information from the user's interaction with
it. The model consists of application data and business rules,
and the controller mediates input, converting it to commands for the
model or view
AngularJS uses client side MVC pattern. So I guess there is no other option then to include validation logic also to the client side in some way?
What would be the best way to write a robust AngularJS application? MVC on client side and some kind of MC (model, controller) on server side?
Does that mean, that MODEL and CONTROLLER are in one way duplicated (client/server)?
I know my question is somehow weird, but I think the reason is, that I am somehow acustomed to traditional server side MVC pattern. I am sure there is someone, that have already done same transition.
Not at all a weird question - I've been trying to sell Angular to a lot of java developers and they ask this. I asked it myself when I was learning (I'm still learning, btw)
If you take a 'conventional' java webapp as you've described and Angular-ize it, you've got to first take your server and make it a RESTful API. Remove the JSPs, etc. This is actually the hard part, IMO, of writing an Angular app - getting the REST API right. The key for me to deciding what logic needed to go into the server was thinking of it as a pure api and forgetting for the moment that it will have a front end.
That question really helped me - if someone tries to save a given resource and that resource doesn't have valid data there's no front end to tell them - they're hitting the API directly so the API needs to reject it. So, the back end is responsible for the deep validation. This applies to your business logic as well. Assume someone is using just the API and it will become clear what your server needs to do.
The server needs also to vend data in (probably) json format (I use Spring MVC + Jackson), so it's responsible for exposing the model to Angular, and communication with the database.
So what's the MVC then on the Angular side?
Model: The data that comes from the REST API. If the API is vending JSON, then these objects will already be 1st class javascript objects.
View: HTML, and directives when you need to manipulate the DOM
Controller: (and custom services that you've factored out of your controllers..)
Queries the REST API and puts what's necessary for the View on the $scope
Provides callbacks for directives to respond to events that might then require calls back to the server.
Validation: usually via a callback to a directive. Will likely overlap some of the validation you've already put in the server, but you don't want your user to wait for the server to validate everything - the client should know something about the validation to give the user immediate feedback.
Business logic: Pretty much the same story as validation.
But why the duplication of logic in the client and in the server? Mostly because you're not writing one app, you're writing two independent things:
a REST API that needs to be robust and usable without a front end
a GUI that needs to give immediate feedback to a user and not necessarily wait for a server.
So, short answer - get the REST API right by forgetting that there will be a UI, and what goes into Angular will be much clearer.
I think the term "business logic" is a bit of a misnomer here. The "business" of a clientside app is the business of handling the user interface. It's not going to be things like security rules and proprietary logic or other sensitive intellectual property.
So in Angular the division is (generally):
Controller (controller): for manipulating the data (scope) behind your UI.
Directives : for setting up the DOM to communicate with the controller via scope, and for manipulating the DOM.
Templates (view): To assign directives to elements of the DOM.
Scope (model or viewmodel): for carrying data between all pieces of the system.
Services : Injectable, reusable bits of code. Usually for dependencies like handling Ajax, cookies, or other I/O.
It's really almost MVVM and not MVC.
As for your "business" logic or rules... anything requiring security must always be secured at the server level.
It's important to understand that in some versions of the MVC pattern, the data as well as the logic that manipulates the data both reside in the "model" layer (with the "controller" layer doing nothing but binding). In AngularJS, however, the data ($scope) alone resides in the "model" layer, while the logic that manipulates the data ($scope) resides in the "controller" layer.
I love what #Roy TrueLove says. But let me say that this is the ultimate way of using angularjs. Of course, you have to learn to do your applications this way, if you want to get the most benefit of angular. I pray to be there some day.
In the meanwhile, during your learning, and during your transition to fully using angularjs as your client side main way of doing things, you can start using it for some small mission here and there, and gradually get accustomed to it and to its way of thinking.
I encourage to gradually embracing it and to go slowly slowly, but surely, I guaranty, sure.
Angularjs is designed to serve this approach, as it can work on the smallest task as good as it can do the biggest one. For example, this first time I used angular was just to show names while the user types ids.
I agree with the answers here. Some more comments. When you write an applicacion, you first need to concentrate on the problem domain. And create a software model of some real business. For example, if your problem domain is a shopping, some requirements that you need to model might include:
The credit card should be valid.
If you pay with a credit card of brand X, you will receive a 10% of discount.
The shop cart should contain at least one item to perform the checkout
The items must have stock before allow users to add them to the shop cart
The implementation of these requirements will model your problem domain, this is your business logic.
Angular is a frontend framework and toolkit. It is a web frontend. If you implement this in a web frontend, you will miss the oportunity to reuse your model from other frontend or interface, like a mobile or a desktop application.
So, ideally, your business logic implementation needs to be decoupled from any user interface framework and decoupled from any persistent framework also. Then, you will have your interface objects that will deal with user interface problems and will comunicate with your business logic objects. This can be a Spring MVC controller, and/or an Angular controller or service.
There is a sample application you can take a look at, that follow the principles mentioned here.
I seems to be having this question as well, as some organizations just craze for new technologies - "I want cloud...wait, I want lightweight", its hard to justify whether it deserve for the switch to a lighther framework.
I develop webapplications using Spring/JBoss seam/JSF and on MVC framework all the time. Most of the time java scripts will reside for the presentation layer validations and the main action classes/entities and business logic will reside in Java code. After some basic hands-on on Angular, I started to get what they meant by MVC as they abstracted another level on the presentation layer, where we can have our own views and controllers on the front end. To answer your question, just like everyone's comment the best way is to lay it on the presentation layer.
As for security point of view, I believe heavy or sensitive business rules should reside on the server side as we do not want to expose it to the world. If the business logic is developed poorly, one can easily find the weakness on our code and exploit it.
Here's my thought for framework like Angular is like a small shop/SOHO handling customer, and they have a few people and really efficient and fast.They cater well for customers facing business and delivery/receive goods efficiently(REST, JSON). They do have designated roles and tasks, but some worker perform more than a tasks. The shop also vulnerable to thief or robbers as usually they don't emphasize heavy security.
As for server side framework like Spring/Struts 2, imagine a modern corporation(CMM Level 5) with different level of management and capable of handling bigger business(batch jobs, web services, enterprise bus). They do handle customer, but not directly, often go through brokers or even retail shops. Security wise a corporation is more robust, and often securities on the front door, or important information are protected in a safe(encryption/sign-on).
My approach is always the bottom-up approach. Starting from the Database Design, with properly constructed / related tables, stored procedures when needed, then add the Entity Framework to the solution or use ADO.Net if EF is not an option. Then develop the Business Logic, and the Models to get the data in and out the database.
With the Models established, we can now go two routes: Developing MVC Controller, and / or developing WebAPI controller. Both controllers can have access to the Models, it's just a matter of instantiating the classes and invoking the methods.
You now have the option of setting up MVC Views that are controlled by the MVC controller, or, entirely separate set of HTML pages or SPA (Single-Page Application hosted on NodeJS).
With the entirely separate set of HTML page, you will need to use WebAPI controllers, with Get, Post, Put, and Delete methods, and be sure to include token back and forth to identify your client, and enable CORS (for Cross Origin Request)
With MVC Views, you can identify your clients using the controller attributes, and / or sessions and no need to worry about CORS, and, you can even make your Views Strongly-Typed if needed. Unfortunately if you have a set of UI developers they will have to work on the same MVC solution.
In both cases, you can use AngularJS to transport data back and forth from / to the controllers.
IMHO the concept of AngularJS controller is not the same with C# MVC or C# WebAPI controller. AngularJS controller house all the javascript logic as well as the calls to endpoints via the "ApiFactory", whereas C# controllers are nothing but Endpoints in the server side that accept and respond to UI requests.
I'm confused about what code I should instantiate directly in Backbone.js. Should I create a generic object App that instantiates my views? Should I instantiate an App View that instantiates all the other views on the page and coordinates everything? Should I create views, models and collections and attach them to the window ?
Also, are controllers even necessary? So far I'm not finding any use for them and they are missing from many of the examples out there. Should I instantiate a controller and have it create the other objects as I do in other languages' MVC frameworks?
My guess is I am free to do what I want but I would prefer some advice from somebody who has used it quite a lot.
Controllers are useful for managing the hashbang URL.
If you don't have multiple pages, states you want to save or want to use the back and forwards buttons then controllers have no use.
Most examples of backbone I've seen have a AppView class that manages views and collections.
See the Annotated Example
Generally speaking, a router or controller would be the centerpiece of your application, although it may be your own hand-rolled init or global object. Backbone provides utilities to you; it doesn't provide an entire soup to nuts setup.