Angular ES6 - 如何组织控制器?

时间:2016-08-29 14:54:12

标签: angularjs ecmascript-6

我有一段代码:

'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'
            });
    });

我有几个问题:
1.如果我在config之前分配控制器,如.controller('ModalCtrl', ModalCtrl),是否违反良好做法? 2.是否可以在routeProvider内分配多个控制器,如controller: ['ShowVersionCtrl', 'ModalCtrl']
3.设置全局控制器的最佳方法是什么?是否有可能设置其中几个?
4.在ng-controller config中指定控制器后,是否需要将routeProvider添加到注入的模板中?

2 个答案:

答案 0 :(得分:1)

  1. 我想说最好将配置和控制器分开放在不同的文件中。你的应用程序很小而且你不想这样做 - 我建议在config之后启动控制器,因为在AngularJS中,生命周期配置总是在所有控制器之前初始化。所以看看这样的订单会更自然。
  2. 这是answer这个问题。但回答是 - 不,你不能,尝试链接解决方案。
  3. 就我提出这个问题而言,你想要一些全局的东西来包装你所有的其他组件。我认为最好将应用程序划分为逻辑组件,并将它们分层次地包含在内。因此,您将了解数据在应用程序中的流动方式以及负责每个应用程序部分的组件。
  4. 您不需要ng-controller,但是您需要设置<ng-view>指令让我们知道您希望控制器与其控制器相关的部分位置。

答案 1 :(得分: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 }

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