Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have controllers in separate file in AngularJS

I look around a bit and didn't find an answer that fit with my current situation. I have a app.js file:

'use strict';

var demoApp = angular.module('demoApp', [
    // Dépendances du "module" <-- demoApp
    'ngRoute',
    'routeAppControllers',
    'todoList'
]);

demoApp.config(['$routeProvider', '$locationProvider',
    function($routeProvider, $locationProvider) { 

        // Système de routage
        $routeProvider
        .when('/home', {
            templateUrl: 'views/home.html',
            controller: 'homeCtrl'
        })
        .when('/contact/:msg?', {
            templateUrl: 'views/contact.html',
            controller: 'contactCtrl'
        })
        .when('/todolist', {
            templateUrl: 'views/todolist.html',
            controller: 'listeCtrl'
        })
        .when('/testfiltre', {
            templateUrl: 'views/testfiltre.html',
            controller: 'demoFiltreCtrl'
        })
        .when('/testCreationfiltre', {
            templateUrl: 'views/testcreationfiltre.html',
            controller: 'demoCreationFiltreCtrl'
        })
        .otherwise({
            redirectTo: '/home'
        });
    }
]);



var routeAppControllers = angular.module('routeAppControllers', []);

routeAppControllers.controller('homeCtrl', ['$scope',
    function($scope){
        $scope.message = "Bienvenue sur la page d'accueil";
    }
]);

routeAppControllers.controller('contactCtrl', ['$scope','$routeParams',
    function($scope, $routeParams){
        $scope.message = "Laissez-nous un message sur la page de contact !";
        $scope.msg = $routeParams.msg || "Bonne chance pour cette nouvelle appli !";
    }
]);

routeAppControllers.controller('listeCtrl', [function(){}]);

I have todolist module in todolist_controller.js:

var todoList=angular.module('todoList',[]);

todoList.controller('todoCtrl', ['$scope',
    function ($scope) {

        var todos = $scope.todos = [];

        $scope.addTodo = function () {
            var newTodo = $scope.newTodo.trim();
            if (!newTodo.length) {
                return;
            }
            todos.push({
                title: newTodo,
                completed: false
            });

            $scope.newTodo = '';
        };

        $scope.removeTodo = function (todo) {
            todos.splice(todos.indexOf(todo), 1);
        };

        $scope.markAll = function (completed) {
            todos.forEach(function (todo) {
                todo.completed = completed;
            });
        };

        $scope.clearCompletedTodos = function () {
            $scope.todos = todos = todos.filter(function (todo) {
                return !todo.completed;
            });
        };
    }
]);

I have my index.html page:

<!DOCTYPE html>
    <html lang="fr" ng-app="demoApp">
        <head>
            <meta charset="utf-8" />
            <title>Demo App</title>        
            <link rel="stylesheet" href="styles/style.css">
            <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js"></script>
            <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-route.js"></script>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-i18n/1.4.2/angular-locale_fr-ca.min.js"></script>
            <script src="scripts/controllers/app.js"></script>
            <script src="scripts/controllers/todolist_controllers.js"></script>
        </head>
        <body>
            <div ng-view>
            </div>
            <nav>
                <a href="#/home" class="btn btn-primary">Page d'accueil</a>
                <a href="#/contact" class="btn btn-success">Page de contact</a>
                <a href="#/todolist" class="btn btn-primary">Todo list</a>
                <a href="#/testfiltre" class="btn btn-success">test filtre</a>
                <a href="#/testCreationfiltre" class="btn btn-primary">test création filtre</a>
            </nav>
        </body>
    </html>

I read that I'm suppose to call, for example, my main module App and all my other module file should start with: angular.module('App').controller(...

But, this would imply that if I change the name of my app from 'app' to 'my_app' for example, I would have to go trough all my controllers and change 'app' for 'my-app'.

I would like to avoid that and just be able to import my file in index.html and just have to declare it in the dependencies of my 'app' module.

like image 944
Kévin Duguay Avatar asked Dec 11 '22 19:12

Kévin Duguay


1 Answers

Angular Structure

When you build an angular app you should separate as much as possible to give your code readability. You should create a module for each page/part of your web app.

Example

Here is an example of this type of structure, I wrote this and use it as a base for angular apps.

app folder

This folder holds all of your components and routes.

routes.js

This file has the states of your project and is its own module

app.js

This file is just the base where you can call all your other modules as dependencies.

var app = angular.module("myApp",   [
                                    'ui.bootstrap',
                                    'ngAnimate',
                                    'myAppRouter',
                                    'myAppHomeCtrl',
                                    'myAppHomeService',
                                    'myAppNavbarDirective',
                                    'myAppNavbarService',
                                    'myAppLoginCtrl',
                                    'myAppLoginService'
                                ]);

You can see all of the different modules written and added here. See the way this is called myApp? well we call that part in the html

<html ng-app="myApp">

components

this will contain things like "home" and "contact" these folders should have everything then need in little self contained html, controllers and services.

controller/module

This is the bit that really answers your question, to add a new module for a controller you do as follows.

angular.module('myAppHomeCtrl', []).controller('homeCtrl', ['$scope', 'homeContent', function($scope, homeContent){

    $scope.dataset = homeContent.getContent();
    $scope.header = homeContent.getHeader();
    $scope.subheading = homeContent.getSubheader();

}]);

service/factory

So you can see that in the module we call a factory, this is also in this folder and looks like this.

angular.module('myAppHomeService', [])

.factory('homeContent', function(){
  return {
    getHeader: function(){
        return "Welcome Human";
    },
    getSubheader: function(){
        return "To Joe's Awesome Website";
    },
  };
});

Back to index.html

So back in our index we can add all of these modules in <script> tags like this.

<!-- Angular Modules -->
<script type="text/javascript" src="app/app.module.js"></script>
<script type="text/javascript" src="app/app.routes.js"></script>
<script type="text/javascript" src="app/components/home/homeCtrl.js"></script>
<script type="text/javascript" src="app/components/home/homeService.js"></script>
<script type="text/javascript" src="app/shared/navigation-bar/navbarDirective.js"></script>
<script type="text/javascript" src="app/shared/navigation-bar/navbarService.js"></script>
<script type="text/javascript" src="app/components/login/loginCtrl.js"></script>
<script type="text/javascript" src="app/components/login/loginService.js"></script>

In production you will minify all these but you can just call them alll like this whilst in dev.

Conclusion

To conclude I'll do a summery to make sure you have everything you need to get your modules to work

  1. go to your app.js (main angular module) and app the name to it.
  2. go to your components and create the new module
  3. go to the index.html and add your script tag that links to the new module
  4. now you can use the controllers and all the components as you wish

I hope this guid to angular structure helps you. Good Luck

like image 145
Joe Lloyd Avatar answered Dec 24 '22 19:12

Joe Lloyd