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.
Related
I have just started working in angular.js and I have created separate angular applications (using ng-app) for separate modules of my application for modularity sake so that change in one module does not bring down the whole application.
Now, i am running into a issue of redirecting from a search form common across all modules to a particular page (in a specific module). I thought of saving the value in $rootScope, but while debugging, I found that $rootScope is per ng-app, so, it will not work.
Am I wrong in designing the application into separate angular applications and should I move everything back into one ng-app? or is my application structure correct and I should look for another way of passing value?
EDIT: - I think I did not provide enough detail earlier.
My application is structured as follows:
module1
- controller\controller-module1.js
- service\service-module1.js
- css\module1.css
- view\ <multiple html files>
module2
- same structure
I was actually using the service-module to make REST calls to the server till now, rather than sharing data.
All the modules are defined with their separate dependencies in app.js:
angular.module('Module1App', ['Module1App.controller','Module1App.service']);
angular.module('Module2App', ['Module2App.controller','Module2App.service']);
controllers and service of each module are defined in their respective controllers-module.js and service-module.js, which reside in different directories as per the structure above.
So, to include the controller and service of a particular module(of, say, module1), I declare the following in a view of that module
<script src="/APP_GUI/modules/common/service/services-common.js"></script>
<script src="/APP_GUI/modules/reports/service/services-module1.js"></script>
<script src="/APP_GUI/modules/common/controller/controllers-common.js"></script>
<script src="/APP_GUI/modules/reports/controller/controllers-module1.js"></script>
So, if I have to move all ng-controllers (defined in separate directories as per the module structure above) into one ng-app (app.js above), I will basically end up including all the controller.js and service.js in all the html views, which will basically mean that if there is an error in any one of the js files, my entire application will be down (i have tried it out).
So, unless I have misunderstood something, I cannot move all ng-controllers under a single app.js.
I am going to try out using shared services to share data.
Please let me know in case anybody has something to say on my conclusion.
I don't think using many ng-app is a good approach. I suggest you using many ng-controller in separate file instead.
You can keep variables inside objects instead of using $scope, which most tutorials you'll find online don't explain.
For example:
/// Define the app
app = angular.module('MyApp',[]);
///Add a cotroller
app.controller('MyFirstController', ['$scope', function($scope){
/// using 'this' you can write local properties
this.firstLocalProperty = 'first Value is acessible only in MyFirstController';
this.secondLocalProperty = 'second Value is acessible only in MyFirstController';
$scope.firstSharedAppProperty = 'This is Shared between all controllers in app';
}]);
app.controller('MySecondController', ['$scope', function($scope){
/// here you can use shared and local properties, you may access shared things in $scope
this.fistProperty = $scope.firstSharedAppProperty;
}]);
You'll see that
> MySecondController.firstProperty
'This is Shared between all controllers in app'
but
> MyFirstController.firstProperty
'first Value is acessible only in MyFirstController'
MyFirstController.firstProperty keeps it's original value because it's not shared.
Basically, you should use different controllers for different templates instead of using different modules. Using controllers, you may share items between them in the $scope variable. Or you can keep variables private using this reference inside objects.
Take a look in this article and you may understand better this way.
You should be using multiple controllers and then using a common service shared between your services. Services in angular are singletons, so they can be shared over and over and over again, and will be common across the board, including between applications if you inject the shared functionality as another application.
var app = angular.module('firstApp');
app.service('myService', function(){
var self = this;
return{
getValue: function(){return self.value},
setValue: function(value){self.value=value}
}
});
app.controller('firstController', ['myService', function(myService){.....}]);
app.controller('secondController', ['myService', function(myService){....});
var secondApp = angular.module('otherApp',['firstApp']);
secondApp.controller('otherController', ['myService', function(myService){.....}]);
more importantly, if its doing anything more than just storing values you can inject functionality for better testing!
I'm planning out an application that ideally I'd like to keep decoupled from Angular, so all the dom interaction will go into an Angular layer but the core business logic will be kept in a standalone app that is totally unaware of Angular. The two will communicate via Angular services that are able to send messages to the core application.
The standalone app will most likely use requirejs to handle dependency injection.
What I'm unsure of is how to get a module that may be declared something like this:
define('AppInteractor', ['require'], function(requre){
// Set up interactor functionality
});
Into an Angular service.
My first though was to have some kind of adapter like this:
define(['AppInteractor', 'angular'], function(interactor, angular) {
var app = angular.module('appInteractor', []).service('AppInteractor', interactor);
});
This would register the AppInteractor as a service within an angular module, the problem with this approach seems to be that because requirejs loads things asynchronously the service hasn't been set when the angular code runs. It also seems to end up with angular loading twice which presumably also doesn't help matters.
I've seen a few articles covering loading all Angular components via require but I was hoping there might be simpler way to make this work.
Can anyone recommend how I might make this work?
If you are going to add a service after the main modules initialization, I recommend you add it to your application module
define(['AppInteractor', 'angular'], function(interactor, angular) {
// There is no second parameter, because we are getting an existing
// module, not creating a new one.
var app = angular.module('appModule');
app.service('AppInteractor', interactor);
});
Otherwise, if you want to group all your other logic in a different module, you will need to import the module and add it as a requirement of your application module.
define(['AppInteractorModule', 'angular'], function(interactorModule, angular) {
var app = angular.module('appModule', [interactorModule.name]);
});
I also recommend you use a tool like ES6 (6to5, traceur), browserify or Typescript for your module management, and then compile to AMD. I find it easier and cleaner for development.
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.
hope things are going well.
I'm attempting to setup my development environment to be able to effectively follow the AngularJS tutorials on http://egghead.io/. I've followed the tutorial on http://docs.angularjs.org/tutorial and have since then been playing around with the angular-seed skeleton. I have successfully set up the angular-seed skeleton and am able to fully run it.
When I attempt to create js files with functions, such as the one in video 2. I'm not able to properly bind it to html element on index.html. I believe the issue may be with how routing is implemented in the angular-seed. I have node.js installed and am able to start the web server from the scripts folder in the angular-seed.
I'm really excited to begin working with AngularJS after I had the opportunity to work with ASP.NET MVC 4. I really like the information John provides in the tutorials on egghead.io, but I'm currently unable to fully emulate his instructions. It looks like he is JetBrains WebStorm, but I have no interest in purchasing it, if possible.
Any help would greatly be appreciated.
Thanks!
Edit 1:
For Example. In video 2 on the egghead.io tutorials. He creates a js file called main.js where he put a customer function and refers to it as an angular controller in index.html:
function FirstCtrl($scope){
$scope.data = {message: "Hello"};
}
Wouldn't a controller need something to exent of:
angualar.module('myApp',[]).controller('FirstCtrl', function(...){});
For angular to have it work as a controller on index.html? I'm able to add some of these functions to controllers.js of the angular-seed and make them work to some extent. Would it best to perhaps still use angular-seed and put the controllers/model/etc he displays some way into it's structure?
I ended up using angular-seed and placing the controllers/services/etc he is creating into controller.js for the first few videos. I was able to successfully output the correct information he is displaying in the videos. By the end of video 5, my code in controllers.js looked something like this:
'use strict';
/* Controllers */
var myApp = angular.module('myApp', []);
myApp.factory('Data', function(){
return {message:"I'm data from a service"}
})
myApp.controller('FirstCtrl', function FirstCtrl($scope, Data){
$scope.data = Data;
});
myApp.controller('SecondCtrl', function SecondCtrl($scope, Data){
$scope.data = Data;
$scope.reversedMessage = function (message) {
return message.split("").reverse().join("");
}
});
At first I was using sublime text 2 and command line (node.js expressjs server), but recently I started using Visual Studio and created an empty website. I transferred all the folders/files of angular-seed into the website structure and I longer need to run node.js expressJS from the scripts\web-server.js. VS2013 has angularJS auto-complete features so it makes it easier.
I really like his tutorials and I'm glad I'm now able to successfully follow them to start learning angularJS.
Thanks!
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/