0

I have a piece of code:

'use strict';
/*jshint esnext: true */
/*global angular: false */

import ModalCtrl from './controllers/ModalCtrl';
import ShowVersionCtrl from './controllers/ShowVersionCtrl';
import TodoListCtrl from './controllers/TodoListCtrl';


var app = angular.module('Todo', ['ngRoute'])
    .controller('ModalCtrl', ModalCtrl)
    .config(($routeProvider) => {
        $routeProvider
            .when('/', {
                templateUrl : './templates/main.html',
                controller: 'ShowVersionCtrl'
            })
            .when('/list', {
                templateUrl : './templates/list.html',
                controller: 'TodoListCtrl'
            })
            .when('/add', {
                templateUrl : './templates/add.html',
                controller: 'TodoListCtrl'
            })
            .when('/search', {
                templateUrl : './templates/search.html',
                controller: 'TodoListCtrl'
            });
    });

And I have several questions:
1. Is it contrary to good practices if I assign controller before config, like .controller('ModalCtrl', ModalCtrl)?
2. Is it possible to assign multiple controllers inside routeProvider, like controller: ['ShowVersionCtrl', 'ModalCtrl']
3. What is the best way to set global controller? And is it possible to set several of them?
4. Do I need to add ng-controller to injected template after I specified controller in routeProvider config?

krzyhub
  • 6,285
  • 11
  • 42
  • 68

2 Answers2

1
  1. I would say it is better to separate config and controllers in different files. And your app is small and you don't want to do that - I recommend to initiate controllers after config because in AngularJS lifecycle config is always initialize before all controllers. So it will be more naturally to look at such order.
  2. Here is answer to this problem. But answer is - no, you can not, try solution in link.
  3. As far as I got this question you want something global to wrap all your other components. I think it is better to divide your application to logical components and include them in the partial hierarchically. So you will understand how data flows in your app and which components responsible for each of app parts.
  4. You don't need ng-controller, but you need to put <ng-view> directive to let know angular where do you expect to see controller related partial with it's controller.
Community
  • 1
  • 1
Kanso Code
  • 7,479
  • 5
  • 34
  • 49
1
###################################################################################
# My suggestion is that use 'Classes' if you are going the ES6 route. Separation is
# necessary when using ES6.

# You will need 'ng-controller' in your injected 'Template'
# e.g. <div ng-controller="profileCtrl as profile"></div>

# You cannot assign multiple 'Controllers' to a specific template. Separation is necessary.

# You can have only 1 Global 'Controller' e.g. for a Landing page of an App, then have
# separate 'Controllers' to handle different pages e.g. profileCtrl for profile page,
# settingsCtrl for settings page etc.

# Handle all your 'import' in a 'Module' file, handle data stuff in a 'Service' file, 
# handle all your template manipulation in a 'Controller' file.
# For example i would create a totally separate folder to handle routing and
# totally separate folders to handle login, profile, changePassword etc. e.g.
# Folder 1 = 'Routing' folder which includes 'routing.module.js' and 'routing.svc.js'.
# Folder 2 = 'Profile' folder which includes 'profile.html', 'profile.ctrl.js', 
# 'profile.module.js' and 'profile.svc.js'.

# Note that naming does not matter ...'ctrl' = 'controller' ... 'svc' = 'service'
# Refer to working example below. 
###################################################################################

###################################################################################
# Folder 1  : Routing
# Main Folder = Foo ... Folder 1 and Folder 2 are inside Foo Folder 
# angular.module('foo.routing', []) ... Shows main folder is Foo Folder
# Handle all your routing to different pages in this folder 
# 'routing.module.js' and 'routing.svc.js'
###################################################################################

# routing.module.js

'use strict';

import { RoutingSvc } from './routing.svc';

let routingModule = angular.module('foo.routing', [])
    .factory('routingSvc', RoutingSvc.factory)
    .config(function(routingSvcProvider){
        //...etc
    });

export default { routingModule };

//---------------------------------------------------------------------------------

# routing.svc.js

'use strict';

class RoutingSvc {
    constructor(){
    }

    createRoutes($stateProvider, config){
        $stateProvider
            .state('login', {
                url: '/login',
                templateUrl: `app/features/login/login.html?v=${config.version}`
            })
            .state('forgotPassword', {
                url: '/forgotPassword',
                templateUrl: `app/features/forgotPassword/forgotPassword.html?v=${config.version}`
            })
            .state('resetPassword', {
                url: '/resetPassword/{token}',
                templateUrl: `app/features/resetPassword/resetPassword.html?v=${config.version}`
            })
            .state('profile', {
                url: '/profile',
                templateUrl: `app/features/profile/profile.html?v=${config.version}`
            });
    }

    static factory(){
        return new RoutingSvc();
    }
};

export { RoutingSvc }

###################################################################################
# Folder 2  : Profile Page
# Main Folder = Foo ... Folder 1 and Folder 2 are inside Foo Folder
# angular.module('foo.profile', []) ... Shows main folder is Foo Folder
# Handle all profile stuff in this folder 
# 'profile.html', 'profile.ctrl.js', 'profile.module.js' and 'profile.svc.js'.
###################################################################################

# profile.html

<div ng-controller="profileCtrl as profile">
    <div layout="row">
        <md-subheader>Profile</md-subheader>
    </div>
    <div layout="row">
        <md-card class="md-whiteframe-z2" flex>
            <md-card-content layout="column">
                <md-input-container>
                <ng-md-icon icon="person" flex="10" size="16" ></ng-md-icon>Name : {{profile.getName()}}
                </md-input-container>

                <md-input-container>
                <ng-md-icon icon="place" flex="10" size="16" ></ng-md-icon>Location : {{profile.getLocation()}}
                </md-input-container>

                <md-input-container>
                <ng-md-icon icon="contacts" flex="10" size="16" ></ng-md-icon>Title : {{profile.getTitle()}}
                </md-input-container>

                <md-input-container>
                <ng-md-icon icon="email" flex="10" size="16" ></ng-md-icon>Email : {{profile.getEmail()}}
                </md-input-container>
            </md-card-content>
        </md-card>
    </div>
</div>

//---------------------------------------------------------------------------------

# profile.ctrl.js

'use strict';

class ProfileCtrl {
    constructor(sessionSvc, profileSvc, $scope, $state) {
        this.sessionSvc = sessionSvc;
        this.profileSvc = profileSvc;
        this.$scope = $scope;
        this.$state = $state
        this.init();
    }

    init(){

    }

    getName(){
        return `${this.sessionSvc.firstName} ${this.sessionSvc.lastName}`;
    }

    getLocation(){
        return `${this.sessionSvc.location}`;
    }

    getTitle(){
        return `${this.sessionSvc.title}`;
    }

    getEmail(){
        return `${this.sessionSvc.email}`;
    }
}

ProfileCtrl.$inject = ['sessionSvc', 'profileSvc', '$scope', '$state'];

export { ProfileCtrl }

//---------------------------------------------------------------------------------

# profile.module.js

'use strict';

import { ProfileCtrl } from './profile.ctrl'
import { ProfileSvc } from './profile.svc';

let profileModule = angular.module('foo.profile', [])
    .factory('profileSvc', ProfileSvc.factory)
    .controller('profileCtrl', ProfileCtrl);

export default {profileModule};

//---------------------------------------------------------------------------------

# profile.svc.js

'use strict';

class ProfileSvc {
    constructor($http, $log, config){
        this.$http = $http;
        this.$log = $log;
        this.config = config;
    }

    getProfile(){
        const baseUrl = this.config.legacyApiBaseUrl;
        let serviceSuffix = 'userProfile';
        let fullUrl = `${baseUrl}${serviceSuffix}`;

        return this.$http.get(fullUrl).then(r => 
            { return r.data; }
            , r=> { return r.data; }
        );
    }

    static factory($http, $log, config){
        return new ProfileSvc($http, $log, config);
    }
};

ProfileSvc.factory.$inject = ['$http', '$log', 'config'];

export { ProfileSvc }

//---------------------------------------------------------------------------------
nocholla
  • 122
  • 5