I built a single page app based on this tutorial:
https://scotch.io/tutorials/single-page-apps-with-angularjs-routing-and-templating
this is the file structure that they suggested:
- script.js <!-- stores all our angular code -->
- index.html <!-- main layout -->
- pages <!-- the pages that will be injected into the main layout -->
----- home.html
----- about.html
----- contact.html
the part about the html pages is pretty straightforward - a page to every ng-view. cool...
but the script.js seems to me like a bad modeling.
should I really put all my js code in one file?
it seems to me like this isn't the best way to model it.
what happened if I will have a lot of pages in my single page app?
I will have a long long one js file with all the controllers..
what is the best practice to model a single page app in angularjs?
Thanks!
// script.js
// create the module and name it scotchApp
// also include ngRoute for all our routing needs
var scotchApp = angular.module('scotchApp', ['ngRoute']);
// configure our routes
scotchApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'pages/home.html',
controller : 'mainController'
})
// route for the about page
.when('/about', {
templateUrl : 'pages/about.html',
controller : 'aboutController'
})
// route for the contact page
.when('/contact', {
templateUrl : 'pages/contact.html',
controller : 'contactController'
});
});
// create the controller and inject Angular's $scope
scotchApp.controller('mainController', function($scope) {
// create a message to display in our view
$scope.message = 'Everyone come and see how good I look!';
});
scotchApp.controller('aboutController', function($scope) {
$scope.message = 'Look! I am an about page.';
});
scotchApp.controller('contactController', function($scope) {
$scope.message = 'Contact us! JK. This is just a demo.';
});
This exhaustive styleguide recommends creating folders and organzing your app based on features. https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#application-structure
I recommend reading the whole "Application Structure" section, which really helped me organizing my angular projects
Related
I have a hard time understanding this. I'm attempting to put controllers in separate files so that they only deal with 1 thing, ideally, a partial view
My folder structure is like this...
My app.js file is like this.
angular.module('mikevarela', ['ui.router', 'mikevarela.controller.home', 'mikevarela.controller.about', 'mikevarela.controller.audio'])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: '../partials/home.partial.html',
controller: 'HomeController'
})
.state('about', {
url: '/about',
templateUrl: '../partials/about.partial.html',
controller: 'AboutController'
})
.state('audio', {
url: '/audio',
templateUrl: '../partials/audio.partial.html',
controller: 'AudioController'
});
});
and my controllers each have a module like this...
angular.module('mikevarela.controller.home', [])
.controller('HomeController', ['$scope', function($scope) {
$scope.title = 'Mike Varela Home Page';
}]);
My issues comes with the intial app declaration. I don't want to have to inject all the controllers in the main array app definition, that would be cumbersome and long winded. Isn't there a way to define the controller at the controller file. Kind of like this
angular.module('mikevarela', []).controller('HomeController', ['$scope', function($scope) {
// stuff here
}]);
Use angular.module('mikevarela').controller..... in subsequent files.
angular.module('mikevarela',[]).controller.....
is equivalent to redefining your app. The second param is requires array.
Quoting official angular.module docs
requires
(optional)
!Array.=
If specified then new module is being created. If unspecified then the module is being retrieved for further configuration.
About your Controllers...
I think you're loading the controllers incorrectly.
You don't need to declare controllers as a dependency. Rather stating module.controller('yourController)` makes that controller available throughout the module.
If your controllers are in separate files, all you need to do to make it available is load it in with a script tag. e.g.
<script src="app.js"></script>
<script src="controller1.js"></script>
<script src="controller2.js"></script>
About your Application Structure...
This is not related to your question, but just coming from someone who's developed using Angular, I'd recommend not grouping your application by controllers/ by rather by feature. See: https://scotch.io/tutorials/angularjs-best-practices-directory-structure
I'm rendering template using ngRoute - $routeProvider and I'm trying to render respective controller along with the template. $routeProvider is pointing to that controller and so it gives me an error controller is undefined because I think the App is trying to call the controller before it receives the template.
The templateCtr definition is in the separate JS file.
app.js
...
$routeProvider
.when('/template', {
templateUrl: '/template.html',
controller: 'templateCtr'
})
;
template.html
...
<script src="templateCtr.js"></script>
templateCtr.js
var myApp = angular.module('myApp'); //Getting module reference
myApp.controller('templateCtr', ['$scope', function($scope){
...
}]);
I also came across resolve property using which can load data to be used in controller before view is generated but for that too controller has to present in the memory.
Someone please point me to the correct direction. Thanks!
Im building a big app , and my structure goes like this:
Each module has its own folder structure for controllers, directives, etc...
Each folder has an index.js file and then other files to separates each controller, each directive, etc...
The index.js file contains the definition of the module. For instance for the controllers of the businessModule above:
angular.module('myCompany.businessModule.controllers', []);
There's no dependencies here, but there could be any.
Then in firstCtrl.js, I can reuse that module and add the controller to it:
angular.module('myCompany.businessModule.controllers').controller('firstCtrl', function(){
});
Then the app.js aggregates all the module that I want for my application by adding them to the dependencies array.
angular.module('myApp', ['myCompany.businessModule', 'myCompany.anotherBusinessModule'],'ngRoute');
Now comes the route that include the other modules view.
My Route goes like:
var myApp = angular.module('myApp');
myApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'pages/home.html',
controller : 'mainController'
})
// route for the about page
.when('/about', {
templateUrl : 'pages/about.html',
controller : 'firstCtrl'
})
});
Now the question is can i connect a controller that from another module to the specific controller that have this module injected like in my situation when myApp contains myCompany.businessModule.controllers and has firstCtrl ?
Your modules file :
angular.module('myApp').config(function($routeProvider){
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'pages/home.html',
controller : 'mainController'
})
// route for the about page
.when('/about', {
templateUrl : 'pages/about.html',
controller : 'firstCtrl'
});
});
Include it as a dependency when you want to use it.
angular.module('app',[other deps]);
I have a globale routes controller and want to create an additional controller for each page template.
It's done as follows:
var app = angular.module('myapp', ['ngSanitize', 'ngRoute']);
app.config(function($routeProvider){
$routeProvider
.when("/test", {
templateUrl: "./templates/test.html",
controller: "testController"
})
});
app.controller('test', function() {
//...
});
Question: how can I move the controller to it's own testController.js file? I tried it, but then the controller does not work anymore.
Which steps do I have to take if I extract the controller in its own file?
How can I get access to var app module variable from within testController.js?
Do I necessairly have to include each controller as new <script src="js/testController.js"></script> tag entry in my html templates? That would be cumbersome, as I want to split my application into many controllers, and that would result in many many imports.
You can access app by simply declaring it without dependencies:
var app = angular.module('myapp');
app.controller("testController", function() {
});
And yes, you need to include testController.js on every page that needs it.
I'm a beginner in the AngularJS environmnent. In the interest of my company, I would like to combine the power of the Angular framework with the Dustjs templating engine.
The problem is : Dustsjs is compiling files to .js files (I have a Grunt task which is doing that for me in my public folder), not in .html. And, in the documentation of $routeProvider, the 'templateUrl' or 'template' parameters are looking for .html templates.
My app.js :
var app = angular.module('myApp', []);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/', {
template: 'views/myView.js',
controller: 'HomeController'
});
}]);
As you can imagine, I have a weird result since my .js is injected without being parsed.
http://i.stack.imgur.com/5JkRx.jpg
So, my two questions are :
- Am I doing it right to put the .js file path inside the template of routeProvider, or is there another way to get and correctly display the view? In short, what did I do wrong?
- Are there any best practices for combining these two technologies?
Am I doing it right to put the .js file path inside the template of routeProvider, or is there another way to get and correctly display
the view? In short, what did I do wrong?
No you are not right in putting the .js file path. Angular expects it to a HTML markup.
template: '<div>content</div>',
and
templateUrl : 'views/myview.html'
would be acceptable values.
Are there any best practices for combining these two technologies?
One of the ways to go would be to use dust templates as the outer template and let angular routeProvider take care of rendering the dynamic content to be parsed by angular. For example,
home.dust
<html>
<head>
<title>{page_title}</title>
</head>
<body ng-app="myApp">
{>header/}
<div ng-view></div>
{>footer/}
</body>
</html>
header.dust
<div id="menu">Menu</div>
footer.dust
<div id="copyright">Footer</div>
view/myView.html
<div id="content">Hi ((username))</div>
app.js
var app = angular.module('myApp', []);
app.config(['$routeProvider', '$interpolateProvider', function ($routeProvider, $interpolateProvider) {
//This is required as dust templates also '{' and '}' for interpolation
$interpolateProvider.startSymbol('((').endSymbol('))');
$routeProvider.when('/', {
templateUrl: 'views/myView.html',
controller: 'HomeController'
});
}])
.controller('HomeController', function($scope){
$scope.username = "John Doe";
});