AngularJS: When should I create another controller? - javascript

Is there a convention when I should create a new controller in my page?
Is it something like 1 controller per page? PageController
Or something like HeaderController, NavigationController and FooterController which is per component?
Any helpful resource will also help. Thanks a lot!

It is better to create one controller for the page content, and one for each component repeated on the page (navbar, footer ...), in order to be reused on other page.
Bests practices here : https://scotch.io/tutorials/angularjs-best-practices-directory-structure (see "modularize" and "components")

I can't find anything to justify my claims so just count on my 2+ years of experience in angular.
These are the cases where I would create a new controller:
1. A new view in the app.
2. A reusable piece of code (can be integrated with a directive).
3. When there's a lot of logic in a view controller I usually create 'sub-controllers' just so it becomes more lean.
Final say about controller - Angular2 & React are saying goodbye to controllers, so I'd recommend to move controller logic either to services or directives.
Cheers

Related

Is it possible to integrate Angular.js (Angular 1) and AEM (Adobe Experience Manager 6.2)

I cannot include all the things I need an answer to the title, so here is what I concern:
Must a client side framework/lib be required when developing AEM ? If yes what is the best one fits to AEM and easy for development (Angular.js is just the way that I think it is "enough" good and easy for integration).
In case of using angular.js, I have some doubts:
Which is the most outter App (which is initialized with ng-app) and how We load it because AEM component is separated and I can not load most outter in any of them.
IMO, most outter ng-app will be loaded in the template (which is required by all the components, but it is just in theory (I'm not sure about that) and I do not see any example outhere show me how to load JS,CSS files on TEMPLATE creation (not component creation, just for clearly)
Alternative approach, each AEM component will be an separated angular module, and it will bootstraped manually (I'm not sure, too, please help to clarify)
Last but not least, If you have examples (enough complicated, not like hello world) or production project that used this stack (perfect !), please help to let me know, because my biggest concern is "is it possible to do".
Many many thanks in advance !
I am currently using angular JS with AEM successfully.
Which is the most outter App (which is initialized with ng-app) and how We load it because AEM component is separated and I can not load most outter in any of them.
ans: You can create a renderer component for this purpose and make it as an outer app then add the required clientlibs to it. after that you can use the renderers scope as a normal angular application.
IMO, most outter ng-app will be loaded in the template (which is required by all the components, but it is just in theory (I'm not sure about that) and I do not see any example outhere show me how to load JS,CSS files on TEMPLATE creation (not component creation, just for clearly)
ans: Rather than loading it in the template It will pretty easy to add it in the component as a client lib because everything like js / css in AEM we can add it as a client lib
Alternative approach, each AEM component will be an separated angular module, and it will bootstrapped manually (I'm not sure, too, please help to clarify)
ans: Yes you can create a component as an angular application and you can bootstrap it seperately
I have used Angular 1.x with AEM 6.x and created SPA (Single Page Application). Also, created AEM Screens App using Angular 1.x.
There could be many ways to do it, but I have followed the following approach :-
AEM Page template (body tag) with ng-app and added angular dependency for site (clientlib angular 1.x)
Define angular module in your site clientlib(JS) say module.js,
example: var app = angular.module('app', ['ui.router', 'ngAnimate','ui.bootstrap.tpls','ui.bootstrap.modal']);
You can also define state provider for different paths app.config(function ($stateProvider, $urlRouterProvider) {});
Define each component specific module/controller in a specific clientlib(js) file.
example (html): <div ng-controller="LoginCtrl" />
example (client lib(js)) - app.controller('LoginCtrl',
function ($scope) {});

Calling Functions from AngularJs Directive

I need to insert a header in my AngularJS application.
I used to have a header and header controller containing login/logout functions since the header contains the username and login/logout.
Now I changed this to header directive, but in order to use the header in all the application pages I have to repeat writing the login/logout function and get the username in all the other pages controllers which is obviously repetitive and inefficient.
I'm new to AngularJS so I wonder if there is a good practice to solve this issue. May I write these functions in the directive itself instead and just pass the username from the controllers, is it a good practice?
You just have to create a service with login/logout functions.
Then you just have to inject your service in your directive.
Take a look here : https://docs.angularjs.org/guide/services

Building Real World AngularJS apps, how should I declare my controllers in html. Do I need to declare all in the index.html?

I have an application based on e.g. the Northwind database, in which I have built views for each of the different objects to maintain them CRUD-ly, using AngularJS views and the in typical file structure adopted by most devs.
I have an issue I would like to improve, firstly from all examples I have seen, you need to declare your controller on an index.html file. If one module that a user uses does not require, all the other controllers, is it necessary to load all controllers on the client side. Is there a better way to only declare controllers that are need per view?
Is this the normal behaivor of a Single Page LOB, to preload all necessary dependencies, whether required or not?
No. Don't declare your controllers in your HTML.
The less logic you add in your template, the more flexible your app will be.
The problem with including controllers in your HTML is that if some nested controllers have the same instance var (example foobar), then you don't know which one would be displayed :
<div ng-controller="firstController">
...
<div ng-controller="secondController">
...
{foobar}
Then, the best way is to work with modules and routes. With routes, you can tell AngularJS that your HTML should be controlled by aController.
I you are looking for a good app to start with, take a look at this one.
It has been developped by the AnguarJS team and shows some good practices to follow. You can notice that none of the HTML files contain a reference to a controller.

How to define multiple main pages in angularjs?

I want to have multiple main index pages that should be accessable independent from each other. Means: there is no global page providing static links to all of the main index pages. Each should live on its own:
WebContent/indexA.html
WebContent/indexB.html
...
Question: how can I write an angularjs controller that shows these pages, if I do not call the*.html extension, but a get-query on that path?
I want to be able to call:
localhost/indexA?param=123
localhost/indexB?test=xyz
Each of them will then map to their own html page, and the request params are to be processed by the controller of that page only.
Is that possible? If yes, how?
If I understood correctly, that you need to use same code (Controller) on different HTML pages, loaded with different URLs.
First option is to use directives to encapsulate same logical parts (Each directive can have attributes, you can provide them in HTML, depend on how is your HTML structured). This is good, when you do not have any routing in your app now.
Second option is to use ui-router with HTML5 routing (then you can pick parameters from URL), this will probably require you to move more logic on frontend, but it is clear solution, if this is not small project.
Next option is to put required parameters into script tag of HTML and then load them from your controller - this is dirty, but quick way of solving your issue.
Try ui-router for the same.
Based on the parameters you pass, you can choose the active state where you can have your own controller and templateURL

Does Angular JS support routing of multiple views on the same page

Does Angular JS support having multiple ng-view sections each with its own templates on the same page? When setting up its configuration you need to wire up the different url path to different controllers and templates. But when you have multiple views on the same page, then they will each need to adjust their template and controller using the #path value from the url, and to change the view template we'll be need to switch as the #path value changes.
So how would the different ng-view sections play with each other - as each would need to append its own unique #path value to the url. Or is the url path and #value somehow kept as a private construct within each ng-view and therefore allowing multiple ng-view sections on the same page.
Multiple views is a limitation in angularjs and the documentation does not make it clear how to structure an application with complex views properly. Please have a look at Jan Varwig's posts on this topic
How to do nested views in AngularJS (Hint: Don’t)
AngularJS: Views vs. Directives
Relevant Sections:
"Views are not what you use to structure your application!
In fact, views are more of a crutch, a shortcut, to create structures similar to traditional websites, only with angular as a driver. When developing a web application, the way to deal with complex interfaces is to use, in combination:
Scope objects/variables that store your desired view state explicitly
ngSwitch directives on this view state
Directives to include custom templates/perform complex DOM manipulation behavior
Stop thinking of your application in terms of views that need to be loaded. That kind of thinking aligns better with imperative frameworks but doesn't work well in angular."
"View-Containers are meaningless, separated from their semantics through the routes.
The other, secondary gripe that I have with UI-Routers nested views is that they violate another core idea of AngularJS: Your DOM is the main place to describe the structure of your app. Reading a template should give you an idea of what goes where. If you want to edit a user, put a directive into your template:
A reader will immediately see what that directive does and what data it depends on.
If you write the directive correctly it will be location independent, you can place it somewhere else in your app, as long as you pass in a user through the attribute it will work.
Using views litters you templates with meaningless containers, outsourcing the actual purpose of every view into the routes/states defined elsewhere. If you nest routes, the context of every view becomes implicit, it is harder to move them around and the only way to pass data into a view is through the scope."
ng-route does not support multiple ng-view inside ng-app.
You can take a look at ui-router as a project which provides some support for having multiple layouts (including nested layouts) tied to the URL.
Caveat Emptor
Note: UI-Router is under active development. As such, while this
library is well-tested, the API may change. Consider using it in
production applications only if you're comfortable following a
changelog and updating your usage accordingly.
Use ui-router instead of the canned ng-route! ui-router totally has nested views, and its awesome and really easy to learn. I would reccomend using ui-router instead of ngRoute to anyone.
Having done further reading on this, it appears that although functionality for multiple ng-view has had number of requests it was not able to make it into the Angular release, but there is possibility of something in future releases.
In this discussion Misko Hevery pointed out another approach, which is to use ng-include.
Then there is also the custom directive approach in Jan Varwig's posts which Vikas has already cited.
Also found this Angular Multiple View project on github which can be a further approach.
For this sort of thing you can use templates.
Create a file e.g. firstNavigation.html which has your snippet of html. Then call it in the controller like so.
$scope.nav = 'src/partials/firstNavigation.html';

Categories