I create a project structure of a web-app with angular.
I create my directories with services, controllers and views.
Then, my team ask me: where are the models? (Nobody of us have worked with angular)
And I answered that in the service, because is where the data persist.
But Im no really sure, and I cant find useful info about this.
What you are looking for is a factory provider. You can create a factory with a collection inside, and this "class" has operations to handle the collection and sincronize it with the back-end.
See this example:
https://github.com/AngularClass/angular-websocket/blob/master/README.md
You can see how to create a collection and initialize it with data that comes from a websocket.
Aditionally you can create operations to handle the collection
This could be consider a "model" in angular.
It is a best practice to keep business logic in Services (and not in controllers, for example). This is, among other reasons, because controllers are instantiated for each view and Services are singeltons.
You can refer to those great posts for more details:
https://johnpapa.net/sharing-data-in-an-angular-controller-or-an-angular-service/
http://teropa.info/blog/2014/10/24/how-ive-improved-my-angular-apps-by-banning-ng-controller.html
https://toddmotto.com/rethinking-angular-js-controllers/
I'm going to assume from the verbiage you've used that you're referring to Angular 1.x.
Services are typically used by controllers to pull data from a provider not displayed in the view. The provider can be a public api, a static file on your own server, a mongo database, etc.
A model for a controller represents the data being manipulated between the view and the controller (refer to ngModel).
Related
So my understanding is that factories are singletons so any stateful data for a session would be ill placed here.
My next point of call was a service which returns a new instance of the service when injected however I am unsure how I would share one instance of the service to multiple controllers.
Is this an accepted way to solve this issue or does angular provide a better way?
My current use case is that I have a view with some partial views (each partial has it's own controller) and a modal window which takes in a row id and will display data dependant on that data.
I need to be able to share a instance of the service (or equivalent) across these controllers but on a per session basis.
How is this best done?
The singleton exists for one user and loaded SPA. Thats what you would usually refer to as a session. Its a good place to store data that needs to be accessed by different controllers.
As a backend developer I am little bit struggling with Angular UI MVC concept.
I am trying to draw parallels to my backend MVC so I can understand mindset behind Angular better.
On my backend I have services talking to repositories(or DAOs (Data Access Objects) how we called them in past), controllers calling services to do the job(as they only transport data and not do heavy lifting) and talk to the client(ie browser) and my Model is a combo of(DTOs (Data Transfer Objects) and Entities as of ORM).
As I am inherently inspired by having backend only ever to return/accept JSON(big no to JSP,FreeMarker,Velocity and all others which make my testing life so hard). I would say that on my backend I only have Model-Controller. From the backend perspective my View is AngularJS as JSON data I return could be labelled as part of my Model but it is definitely not my View.
Now when I start to think about UI MVC as of AngularJS I don't understand who should use $http service to talk to backend. The endless examples scattered across the web do not help me. They are either too minimalist or don't show the usage of $http in the full context(simply called from controllers).
I could argue easily for both.
Case A: If AngularJS treats backend as Model then it is the responsibility of angular's services to call $http to talk to backend to retrieve/post data. Here angular controllers still act as basic transport between View and Model ocassionally calling services to get and process data from backend.
Case B
I could also say, hold on - "no", if angular's controllers role is solely to transport then they should get data from backend and deliver to required destination i.e. angular's service/view(if no further processing required).
So which one is "right"? Or at least widely accepted by UI/fullstack devs?
Controllers should only be connecting data and logic with the view and in the most minimal way possible. A bulky controller suggests that either the view needs to be divided up or logic needs to be abstracted into services. $http calls definitely belong in services. The controller doesn't care how the data comes, just that it comes. So:
// controller doesn't care how
getData().then(function(data) {
VS:
// controller is too concerned with "how"
$http.get('/the/path').then(function(data) {
It is typical to see $http calls in controllers in sample code, but not in professional production code.
I would strongly suggest Case A: having this in a service.
Think of Angular controllers as owning each specific piece of view they are assigned to, with services providing ready-made functionality for those controllers.
Also note that a single page can have many views, each of which could be bound to its own instance of a given controller. So it doesn't really make sense to have $http-based functions etc being instantiated a bunch of times. For a service, it will be instantiated once and then shared across any controller that injects it. This is also a great way to share data between controllers, and is one of the strongest reasons to use a service for any given task.
One other suggestion is that thinking of Angular as MVC can lead to issues. Angular is flexible enough to follow multiple design patterns, hence the MVW (Model View Whatever) moniker, but the majority of applications I have seen tend to follow the MVVM pattern. For this reason I would say that the controller should never have knowledge of $http in most cases.
Why do we need services or factories, we can also do the same thing by making a normal javascript function, or writing the logic in the controller itself.
For example, when i get json data from the server using '$http.get', i can do it by writing a separate service for it but why is it even required when we can directly write its code in the controller?
This is a good question to ask for clarification before digging into Angular as understanding the parts will enable you to write good Angular code and not just do something because you can.
http://i.stack.imgur.com/BKl1Y.jpg
This is a good visual for Angular as an MVC.
The simple answer to your question is that services should be passing information through your controllers to your various pages and routes. All information logic shared across these views belongs in the service. Controllers pass along that information from the view to the service and from it. Information and logic local that view that doesn't need a broader scope can stay in the controller. This is the clean separation that makes Angular a strong framework.
I don't really understand what a model is in AngularJS. I know what a model is in the context of an MVC framework. For example in PHP I would create a model, like ApiModel.php or something like that, and in there I would put all sorts of cool stuff for the controller to work with.
This doesn't seem to be the way AngularJS thinks of models, in fact I can't find any good explanation of how to implement a model in AngularJS, but everywhere talks about them.
What is a model in AngularJS and how do I use them in the traditional MVC way?
A model in AngularJS specifically communicates with its associated views and controllers and notifies it whether there is a change in its state.
A more thorough description of what is a model can be found in the following link:
https://web.archive.org/web/20140502052028/http://www.webdeveasy.com/angularjs-data-model/
This article is relevant to your inquiry.
More specifically, he mentions that
Model classes encapsulate your application’s data and provide an API to access and manipulate that data. The other classes in your application will make requests of models via this API. When data on the model is updated, the model dispatches events that the other classes within your application can react to. Models are appropriate for capturing the domain logic, such as performing calculations or other manipulations.
A model is just the data that your application consumes.
If the data needs to be dynamic (i.e subject to CRUD operations) you would get this data from a remote source like a database (or even a flat-file) using angularjs' $http in a service or factory and then pass it to the Controller.
If you have a small app for read-only data, then you can hard-code it directly into a Controller.
The most popular data format for angularjs applications these days is JSON because of its flexibility.
The view (or front-end) would then access this data that lives on the scope in the Controller using ng-bind or ng-model or interpolation {{...}}
I'm new to AngularJS and having a hard time wrapping my head around the conceptual model.
Let's say I want to have an object hierarchy to model a stash repository: Projects contain Repositories contain Tags. Do I create one app, one module and multiple controllers? (Can a module have multiple controllers?) Separate app per object type? Separate module per object type?
All the various data types will be populated by making REST API queries. Read-only for now. Does that change things?
Also, why are they called controllers? They seem to be models. As far as I can tell the controller is actually the AngularJS plumbing.
Here is my rather simple explanation:
A module is just simply a container for all the bits and pieces of your app (services, controllers, directives, filters etc).
Your application may contain different modules - some that you wrote and other third party ones, such as ngGrid for example.
You define a module like this:
var myAppModule = angular.module('myApp', []);
A controller is where the business logic of your application resides. The controller may handle the model, but it is not the model.
The AngularJS documentation for controllers states:
Use controllers to:
Set up the initial state of the $scope object. Add behavior to the
$scope object.
I break up my controllers in to the logical functions that they are supposed to handle. For example, I've written an app to help with combat tracking in a tabletop RPG. I have a controller that handles martial combat and another that handles magick. I also have another controller that helps with the characters. All these controllers are part of my combat app.
I only have one service that is responsible for querying a REST API to retrieve stats and results from a database.
The AngularJS documentation has improved a lot recently and I would recommend reading through it to give you a rough idea of how things work together!
In your example, I'd have a separate controller for each of Projects, Repositories and Tags. I'd have a service to query your datatypes. These would be grouped as part of one module/app.