【问题标题】:AngularJS (with John Papa Styleguide) + RequireJSAngularJS(与 John Papa 风格指南)+ RequireJS
【发布时间】:2017-03-18 15:15:13
【问题描述】:

我使用 Angular 已经有一段时间了,尤其是使用 John Papa 的样式指南。但我仍然不确定我是否理解正确,特别是关于每个文件一个项目的文件结构。

我尝试在一个项目中将 requireJS 与 angularJS 结合使用,但不幸的是它似乎不起作用...

关于应用程序的一些背景:

这是一个具有一个 main.js 和一个 app.js 的多模块应用程序。每个模块都在自己的 maven-module 中开发,带有一个小的 java-backend 和自己的 url-context。现在所有子模块都在 main.js -> require.config.path 中引用,例如

ma​​in.js:

require.config({
    // Paths to vendor scripts and separate files.
    paths: {
        'myModule': '../../mymodule/mymodule',
        'myOtherModule': '../../myothermodule/myothermodule',
         ... // many more angular modules
    },
    // Create shims for vendor libraries that aren't AMD modules and specify dependencies for them.
    shim: {
        'angular': {deps: ['jquery'], exports: 'angular'},
        'angularEN': {deps: ['angular'], exports: 'angularEN'},
        'angularDE': {deps: ['angular'], exports: 'angularDE'},
        'angularCH': {deps: ['angular'], exports: 'angularCH'},
        'ngResource': {deps: ['angular'], exports: 'ngResource'},
        'ngCookies': {deps: ['angular'], exports: 'ngCookies'},
        'angularRoute': ['angular'],
        'jquery': {exports: '$'},
        'jquery_cookie': ['jquery'],
        'hammer': ['jquery'],
        'materializeClockpicker': ['materialize'],
        'materialize': {deps: ['jquery', 'hammer']},
        'angularMaterialize': ['materialize'],
        'moment': {exports: 'moment'},
        'angularMoment': ['moment'],
        'foundation': ['jquery'],
        'ngTable': {deps: ['angular', 'jquery'], exports: 'ngTable'},
        'nvd3': {deps: ['d3'], exports: 'nvd3'},
        'angularnvd3': {deps: ['angular', 'nvd3'], exports: 'angular-nvd3'},
        'ngSanitize': {deps: ['angular'], exports: 'ngSanitize'},
        'ocLazyLoad': {deps: ['angular'], exports: 'ocLazyLoad'},
        'uiRouter': {deps: ['angular'], exports: 'uiRouter'},
        'ncyangularbreadcrumb': {deps: ['angular'], exports: 'ncyangularbreadcrumb'},
        'treeControl': {deps:['angular'], exports:'treeControl'},
        'ngAnimate': {deps: ['angular'], exports: 'ngAnimate'},
        'ngMap': {deps:['angular'], exports:'ngMap'},
        'angularFileSaver': {deps: ['angular', 'fileSaver', 'blob'], exports: 'angularFileSaver'},
        'nliMenu': {deps:['angular','treeControl'],exports:'nliMenu'},
        'mmFoundationTpls': {deps: ['angular'], exports: 'mmFoundationTpls'},
        'adf': {deps:['mmFoundationTpls', 'sortable'],exports:'adf'},
        'adfBase': {deps:['adf'],exports:'adfBase'},
        'localStorage': {deps: ['angular'], exports: 'localStorage'},
        'angularUiTree': {deps: ['angular'], exports: 'angularUiTree'},
        'angularRecaptcha': {deps: ['angular'], exports: 'angularRecaptcha'}
    },
    // kick start application
    deps: ['../../core/js/bootstrap']

bootstrap.js:

define([
    'require',
    'angular',
    'app',
    'app.config',
    'app.run',
    'app.controllers',
    'jquery',
    'foundation',
    'modernizr'
], function (require, angular) {
    'use strict';

    require(['domReady!'], function (document) {
        angular.bootstrap(document, ['myAwesomeApplication']);
    });
});

app.js:

define([
        'angular',
        'app.controllers',
        'app.config',
        'app.run',
        'appServices',
        'appFilters',
        'appDirectives',
        'angularRoute',
        'ngResource',
        'angularnvd3',
        'ngSanitize',
        'uiRouter',
        'uiRouterExtras',
        'offscreenMenu',
        'ncyangularbreadcrumb',
        'angularFileSaver',
        'treeControl',
        'angularUiTree',
        'adf',
        'adfBase',
        'dashboardPersistence',
        'mmFoundationTpls',
        'localStorage',
        'ngMap',
        'ngTable',
        'ngAnimate',
        'angularMaterialize',
        'materializeClockpicker',
        'angularMoment',

        /*Custom services*/
        'lang',
        'templatingUtils',
        'appUtils',
        'resetUtils',
        'passwordPolicyUtils',
        'nliConnector',
        'nliCaptcha',
        'nliMessages',
        'menuUtils',
        'nliMasterData',
        'validationUtils',
        'messagingUtils',
        'uiCoreServices',
        'angularRecaptcha',
        'cacheUtils',

        //... many more

        'myModuleModule',
        'myOtherModule'
    ],
    function (angular, appControllers, appConfig, appRun) {
        return angular
            .module('portals.nli', [
                'smo.controllers',
                'gkp.services',
                'gkp.filters',
                'gkp.directives',
                'adf',
                'adf.structures.base',
                'adf.nli.persistence',
                'ct.ui.router.extras',
                'fileSaver',
                'LocalStorageModule',
                'mm.foundation',
                'ncy-angular-breadcrumb',
                'ngAnimate',
                'ngMap',
                'ngResource',
                'ngRoute',
                'ngSanitize',
                'ngTable',
                'nvd3',
                'ui.router',
                'ui.tree',
                'treeControl',
                'ui.materialize',
                'angularMoment',

                /* Custom Services */
                'portals.nli.appUtils',
                'portals.nli.resetUtils',
                'portals.nli.captcha',
                'portals.nli.connector',
                'portals.nli.lang',
                'portals.nli.messagingUtils',
                'portals.nli.passwordPolicyUtils',
                'portals.nli.templatingUtils',
                'portals.nli.uiCoreServices',
                'portals.nli.validationUtils',
                'vcRecaptcha',
                'portals.nli.cacheUtils',

                'mymodule',
                'myothermodule'
        ])

        .constant(
            'APP_CONSTANTS', {
             ...
            }
        )

        .constant('Modernizr', Modernizr)

        .value('APP_VALUES', {
            ...
        })

        .config(appConfig)

        .run(appRun);
    });
})();

例如此应用程序中的子模块之一如下所示:

/mymodule
    /mymodule.js
    /mymodule.config.js
    /mymodule.controller.js

mymodule.js:

define([
    'angular',
    'mymodule.config',
    'mymodule.controller'
],
function(angular) {
    'use strict';

    return angular
        .module('myModule', [])

        .constant('APP_CONSTANTS', {
            ...
        })

        .run('APP_CONSTANTS', function (APP_CONSTANTS) {
             ...  
        }]);
    });

mymodule.config:

define(['angular', 'mymodule'], function(angular) {
    'use strict';

    angular
        .module('myModule')
        .config(config);

    config.$inject=['$logProvider', '$stateProvider'];
    function config($logProvider, $stateProvider) {
        $logProvider.debugEnabled(true);

        $stateProvider
           ...
    }

    return config;
});

mymodule.controller.js:

define(['angular', 'mymodule'], function(angular) {
    'use strict';

    angular
        .module('myModule')
        .controller('MyModuleController', MyModuleController);

    MyModuleController.$inject=['$scope', '$log'];
    function MyModuleController($scope, $log) {
        var vm = this;

       /** ====================
        *   (Bindable) Members
        *  ==================== */
        vm.annualConsumption = null;
        vm.calorificVal = null;
        vm.zNumber = null;
        vm.checkValues = checkValues;
        vm.calculateGasConsumption = calculateGasConsumption;

       /** ========================
        *   Implementation Details
        *  ======================== */
        function checkValues() {
            return vm.annualConsumption && vm.calorificVal && vm.zNumber;
        }

        function calculateGasConsumption() {
            return vm.annualConsumption * vm.calorificVal * vm.zNumber;
        }
    }

    return MyModuleController;
});

不幸的是,我在控制台上遇到了异常:

Uncaught Error: [$injector:nomod] Module 'myModule' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.2.18/$injector/nomod?p0=myModule
    at angular.js?v=2017-03-15:78
    at angular.js?v=2017-03-15:1643
    at ensure (angular.js?v=2017-03-15:1567)
    at Object.module (angular.js?v=2017-03-15:1641)
    at mymodule.config.js?v=2017-03-15:6
    at Object.execCb (require233.js:1696)
    at Module.check (require233.js:883)
    at require233.js:630
    at each (require233.js:59)
    at breakCycle (require233.js:619)

也许你可以看看并告诉我出了什么问题?那太好了,因为我在这里真的很难过。 :-( 不使用 requireJS 时我从来没有遇到过任何问题。我真的开始讨厌 require....

【问题讨论】:

    标签: angularjs requirejs


    【解决方案1】:

    编辑这些文件的开头如下:

    mymodule.js:

    define([
        'angular',
    ],
    

    mymodule.config:

    define(['angular', 'mymodule'], function(angular,myModule) {
        myModule.config(config);
    

    mymodule.controller:

    define(['angular', 'mymodule'], function(angular,myModule) {
        myModule.controller('MyModuleController', MyModuleController);
    

    并在某个地方(例如 index.js)引导它,如下所示:

    requirejs(["mymodule","mymodule.config","mymodule.controller"],function(mymodule){
    //bootstrap 'mymodule' by hand without "ng-app"
    });
    

    【讨论】:

    • 所以如果我没看错的话,你没有使用模块的 angular-getter 而是调用主模块文件上的函数配置和控制器?
    • @Vortilion 完全正确
    • 你的方法也可以,但毕竟不是那么清楚。这不是您的代码不起作用的原因。小瓶的原因是您在“mymodule”文件的开头“定义”了配置和控制器。
    • 我认为这就是 require 的目的。我在 main.js 中定义了“mymodule.js”,它还定义了对其控制器和配置文件的依赖关系。如果我不这样做,它根本不会加载文件......我想我必须至少在 main.js 和 app.js 中定义它们。这就是我想要避免的,因为我认为 require.js 的目的是我不必为 main.js 中的每个子模块引用每个 JS 文件?因为如果我这样做,我根本不明白 requireJS 的目的。要么我的 index.html 中有所有 JS 文件,要么我的 main.js 中有所有 JS 文件?
    • 其实你是对的。但是你应该注意到 angularjs 有自己的模块管理机制。当您将它与其他模块机制一起使用时,它可能会中断。在 requirejs 看来,你的 my "myModule" 取决于你的配置和控制器,但 angularjs 不这么认为。
    【解决方案2】:

    你应该像这样改变你的角度 mymodule.js:

    define(['angular'], function (angular) {
        'use strict';
        var ret = angular
            .module('myModule', [])
            .constant('APP_CONSTANTS', {
    
            })
            .run('APP_CONSTANTS', function (APP_CONSTANTS) {
    
            });
    
        requirejs(['mymodule.config', 'mymodule.controller'], function () {
            // do some bootstrap things
        });
        return ret;
    });

    并删除“mymodule” 配置和控制器文件的依赖关系。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-26
      • 2011-01-13
      • 2011-07-22
      • 1970-01-01
      相关资源
      最近更新 更多