So I am writing an angular front end app for an enterprise client and my file structure is as such:
- App (root)
- Assets
- CSS
- JS (plugins, libraries, etc)
- Images
- Fonts
- Common
- Header
-header.html
- Sidebar, etc
- Modules
- HR
- HR.module.js (the module, for this module, yeah kinda confusing)
- HR.routes.js (the routes for this module)
- Employees
- EmployeesController.js (the controller for this specific peice of thsis module)
- EmployeesRepository.js (the factory/service for this app)
So far this has worked out alright (though tips are welcome) the issue i am running into is, if I have two modules (let's say HR and IT) then my main index page needs to utilize the routes from both, but you can only have one angular module per page. I could put all routes in a common app.js file, but that kind of messes with my seperation layout. Is there a solution to this? Or should I use a more elegant file sctructure?
Edit1 - routing
var hrModule = angular.module("hrModule", ['ngRoute', 'ngResource'])
.config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/HR/Employees', { templateUrl: '/Modules/HR/Employees/Employees.html', controller: 'EmployeesController' });
$locationProvider.html5Mode(true);
});
This is a bit tricky.
You either need to:
Consolidate all modules into one application, so that routing is done from one file (this is what I was suggesting in the comments; and this would probably require a simple build system which would build routes based on json files included in the build).
Or you have multiple ng-apps in your window, each with it's own view (something like this: plnkr.co/edit/wpS8LVeEc5gVPS87n5AN?p=preview). This way would mean you need a routing system which hides views dependent on which module is showing, but you can hack away at this functionality.
If you are looking at creating a small build system which has routes defined in one file, I have a starter template here: grunt-angular template. You will need to hack it a little in the tasks if you want to grab multiple routes.
The readme should cover most of it, else feel free to message me.
Related
I recently started working with Angular 6 and while basic scenarios work pretty well, I'm having a hard time making more complex routing scenarios work.
I have so far divided my application up into two major modules (more to come), Authentication and Core.
In the Core module, I have a Core Component which contains Navigation, Header and Footer Components and then a tag.
From the core navigation the user should be able to access major parts of the application such as:
UsersModule - UserListComponent, AddUserComponent, EditUserComponent etc
ProductsModule - ProductListComponent, AddProductComponent, EditProductComponent etc.
As these different modules will be used by different users I was hoping to use lazy loading to load them into the CoreComponent - router-outlet tag. Ultimately it will look like this:
The problem is I'm not sure how to set up my routing as when I try to load any of the components in either UserModule or ProductModule they just replace the contents of the screen instead of being loaded into the CoreComponent's tag.
Here is the code:
app.module.ts
core.module.ts
user.module.ts
Can anyone please help me?
I'm learning Angular for a new job (1 at the moment, then we'll be transitioning to 2 later on). I have experience with ASP MVC but none with client side MVC so this is all new to me from the get go. Most tutorials use this file "app.js" or something along these lines, which I guess registers various things with Angular, like the name of your web app, etc. That's all fine, but I want to know what is the specific purpose of this file?
For example, I'm going through this tutorial currently and this is the code we're doing for routing and controllers:
var AngularWebApp = angular.module('AngularWebApp', []);
AngularWebApp.controller
('LandingPageController', LandingPageController);
var configFunction = function ($routeProvider) {
$routeProvider.
when('/routeOne', {
templateUrl: 'routesDemo/one'
})
.when('/routeTwo', {
templateUrl: 'routesDemo/two'
})
.when('/routeThree', {
templateUrl: 'routesDemo/three'
});
}
configFunction.$inject = ['$routeProvider'];
The reason I'm asking is I have yet to read a single explanation anywhere on what this file is actually for, it seems like we're just dumping a bunch of config settings in here, so is this sort of like in ASP MVC the web.config file? I just want a definitive answer rather than just guessing about it.
app.js (I use main.js) is just a common name given to the root bootstrapping file for an angular project. While you may concat all your js files for a production release, when developing, file separation is obviously a good thing.
When developing an angular project, you create a bunch of modules that do various things, but you need a primary module for your app that you use with the ng-app attribute in your html: https://docs.angularjs.org/api/ng/directive/ngApp
This module sets up dependencies, and usually houses app config, such as routing. Although you don't have to structure your app this way, as in the end it is just a naming convention.
I have a structure to my angularjs app project as below:
I am aiming to have each component have its own controller and service to display portfolio information like images, videos, links etc.
The issue I am having is that the only way I am able to define each controller is by stacking them into my head tag in the index.html file. If I choose to create more pages, I am going to have to do this over and over again, meaning lots of calls, lots of load time etc.
Is there a way to inject each of these controllers into the app.module.js file, so this is the only file that needs to be loaded?
thanks in advance.
You will still have to place a script-tag into your html-file for every script-file you have. For testing/learning purposes you can just put them there by hand. But when this gets to annoying for you, consider using some kind of build tool like Gulp where you can inject them based on folder structure for example.
You can define index.js file for every folder and export this modules with gulp for bundle.js
like
module.exports =
angular.module('app.component.contact', [
]);
and assume that you need sub-folders and different directives at the contact folder like:
---contact
---list
---favorites
then:
module.exports =
angular.module('app.component.contact', [
'angularMoment',
require("./list"),
require("./favorites"),
]);
also parent of the contact like components you can do export operation like that:
module.exports =
angular.module('app.component', [
'ui.router',
require('./about'),
require('./contact'),
require('./home'),
]);
this is the simple logic of the exports from child to parent folders.
At the moment we are in the process of creating a new web application infrastructure.
We initially load a dashboard which is esentially the top bar displaying the logged in user and the set of menus along with it. Clicking on each menu would load a screen (mostly crud screens) in the main section. We areplanning to put each of the crud screens and their components (services, controllers and such) in a seperate module which will encapsulate all the screens from each other, so for example if there is 78 screens there will be 78 seperate modules for each screen. We are also using planing on using Requirejs to load these dependencies dynamically.
The problem however occurs that we need to link the menu with each of the modules for each screen. Typically in a single module based app it would be done like this.
config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/Book/load', {
templateUrl: 'book.html',
controller: 'BookController'
})
.when('/Screen/load', {
templateUrl: 'chapter.html',
controller: 'ChapterController'
});
Where the BookController and ChapterController will be in the SAME module.
However in our case the BookController will be in a BookModule for the book screen and the same applies for the ChapterController. And the routes would be in the initial main module for example AppModule which loads the dashboard initially during startup then.
How would we say for example link the AppModule and the routes with each module for each screen (for example in this case BookController and ChapterController) keeping in mind that we need to load the modules dynamically when NEEDED using requirejs.
(P.S : We are essentially segmenting our application based on feature where feature in our system usually equals screen)
Also any suggestions on any other way we could best structure our app including an answer to the above problem would be very much appreciated.
Regards,
Milinda
Why do you have the route configuration in the initial main module? This creates unnecessary coupling between your modules (ie. your initial module has to know all the possible routes of every module), sort of defeating the purpose of moving your code into modules in the first place.
Each of your modules can have their own route configuration, which will take effect when the modules are loaded. (A consistent naming convention can help avoiding clashes between routes of unrelates modules)
While configuring the routeProvider, you can use lazy loading mechanisms using the resolve attribute of routes: resources referenced here will be resolved before the routeChange event happens, which enables you to wait for any promise resolution or a requireJS loading of a file. This blogpost might help in that regard.
As of this moment, there is no mechanism as far as I am aware for dynamically loading modules at runtime and then incorporating them in an AngularJS app. You can breakdown your app into 78 individual modules loaded via requirejs, but you will still need a single primary module which has all those other 78 as dependencies. It is this primary module which you will then configure all the routes.
There is work going on into a new AngularJS router which borrows from other more flexible routers (i.e. ui-router, etc) which will allow exactly the sort of dynamic loading of modules you are speaking about but as far as I know it won't be available until AngularJS 1.4.
On a large AngularJS application having all my controllers in a single "controllers.js" file seems a little un-maintainable to me. Is there a better way to do this such as:
\js\controllers\myController.js
\js\controllers\yourController.js
\js\controllers\ourController.js
and that also applies for filters, services, directives etc...
There are lot's of ways to organize your code. You can look in the following links
Building Huuuuuge Apps with AngularJS
Code Organization in Large AngularJS and JavaScript Applications
AngularJS Best Practices: Directory Structure
You can follow their standard or you can make your own.
Try to follow the following guidelines:
Contollers shouldn't be too long, if it's too long then it is handling multiple responsibilities
Try to use Directives and Services in your system to reuse your code/logic
Directives are the most powerful things in Angualrjs, try to get maximum advantage of it.
Write Tests; even better you can try to practice TDD with AngularJS
You can manage it like module wise!!
For example , take user view , you make one directory, here its name is user!!
user // directory , now put all controller ,service and directive file into it !!
-- userController.js // controller file
-- userService.js // service file
-- userDirective.js // directive file
-- views // make directory, and put all html file regarding that module into this
--users.html // html file
Hope this will help you!!
See how these two starter projects organize files for a larger-scale application:
https://github.com/angular-app/angular-app/
https://github.com/joshdmiller/ng-boilerplate
You may wish to have a look at this community-driven guide.
The guide describes best practices for organizing the directory structure of a large AngularJS application.
It also makes recommendations on naming and structuring AngularJS modules, controllers, directives, filters and services.
It's also worth it to check out a tool like Lineman.js with the AngularJS application template.
For enterprise AngularJS projects, you may wish to look at this kickstarter which is based on ng-boilerplate.
There's a nice document out there from Google's own team that back up Shivali's example:
https://docs.google.com/document/d/1XXMvReO8-Awi1EZXAXS4PzDzdNvV6pGcuaF4Q9821Es/pub
Something like this:
sampleapp/
app.css
app.js top-level configuration, route def’ns for the app
app-controller.js
app-controller_test.js
components/
adminlogin/
adminlogin.css styles only used by this component
adminlogin.js optional file for module definition
adminlogin-directive.js
adminlogin-directive_test.js
private-export-filter/
private-export-filter.js
private-export-filter_test.js
userlogin/
somefilter.js
somefilter_test.js
userlogin.js
userlogin.css
userlogin.html
userlogin-directive.js
userlogin-directive_test.js
userlogin-service.js
userlogin-service_test.js
index.html
subsection1/
subsection1.js
subsection1-controller.js
subsection1-controller_test.js
subsection1_test.js
subsection1-1/
subsection1-1.css
subsection1-1.html
subsection1-1.js
subsection1-1-controller.js
subsection1-1-controller_test.js
subsection1-2/
subsection2/
subsection2.css
subsection2.html
subsection2.js
subsection2-controller.js
subsection2-controller_test.js
subsection3/
subsection3-1/
etc...
Check this, build your angular app with CoffeeScript, SCSS.
https://github.com/nhim175/modular-angular-skeleton/