Javascript AngularJS+;RequireJS模块定义

Javascript AngularJS+;RequireJS模块定义,javascript,angularjs,Javascript,Angularjs,我有一个相当大的项目,同时使用了RequireJS和AngularJS。一切正常,但看我的代码,模块定义有点混乱。例如,以下是“主”应用程序文件: define(['angular', 'jquery', 'ui-router', 'angular-restmod', 'angular-cookies', 'angular-animate', 'angular-sanitize', '

我有一个相当大的项目,同时使用了RequireJS和AngularJS。一切正常,但看我的代码,模块定义有点混乱。例如,以下是“主”应用程序文件:

define(['angular',
        'jquery',
        'ui-router',
        'angular-restmod',
        'angular-cookies',
        'angular-animate',
        'angular-sanitize',
        'angular-touch',
        'angular-moment',
        'angular-ui-select2',
        'bower_components/jquery-ui/ui/resizable',
        'bower_components/jquery-ui/ui/draggable',
        'bower_components/jquery-ui/ui/sortable',
        'bower_components/jquery-ui/ui/droppable',
        'angularui',
        'angular-hotkeys',
        'splitter',
        'angular-loading-bar',
        'common/components/chart/chart',
        'common/utils/confirmLeave',
        'common/utils/listener',
        'common/components/toolbar/toolbar',
        'common/components/anchor/anchor',
        'common/utils/print',
        'common/components/notifications/notifications',
        'angular-shims-placeholder'], function (angular, $) {

    var app = angular.module('myapp', ['restmod', 'ngCookies', 'ui.router', 'oc.lazyLoad', 'ngAnimate', 'ngSanitize', 'angularMoment', 
        'ui.bootstrap', ui.select2', 'utils.listener', 'ng.shims.placeholder', 'interceptors.exceptions', 'interceptors.security', 'cfp.hotkeys', 'utils.offline', 'components.notifications', 'angular-loading-bar']);

    return module;

});
如果你注意到我定义了amd模块和角度模块两次。它看起来很难看(尽管它确实工作得很好)


我的问题是有没有人找到更好的方法?我看过这个项目,但我对此有所保留。

您没有两次加载模块;您只需加载一次模块,以便在声明应用程序模块的依赖项时可以找到它。作为AMD模块,您在第一次物理加载时就依赖于它们;作为AngularJS模块,您依赖于它们,但只有当它们已经可见时才可能

我们要做的是去掉一些样板代码,使用一个通用的
core.js
AMD模块,它加载我们始终需要的所有库(jquery、插件等)。那么我们的主应用程序文件将仅仅依赖于核心模块

您还可以通过定义AngularJS“core”模块进一步了解这一点。那么你所需要的就是:

define(['core'], function (angular, $) {
    return angular.module('myapp', ['core']);
});
您将其移出,但也使其可在多个模块上对RequireJS和AngularJS进行重用


关于这一点,它看起来像是句法上的糖。考虑到AngularJS与RequireJS的混合已经提供了必要的学习曲线,在没有获得显著优势的情况下疏远语法似乎是一个可以跳过的选择。扪心自问:“我们目前的方法很难看,但我经常这样做吗?这真的值得另一个库和定义angular应用程序的新方法吗?”。可能不会

我最终编写了自己的小实用程序来处理这个问题

define(['angular'], function(angular){
    angular.defineModule = function dm(name, modules){
       var pargs = dm.caller.arguments;

       var filtered = Array.slice(pargs)
            .filter(function (m) { return m && m.name; })
            .map(function (mm) { return mm.name; });

       modules && (filtered = filtered.concat(modules));

       return angular.module(name, filtered);
   };
});
然后你可以像这样使用它:

define(['angular',
        'core',
        'common/services/users',
        'common/services/account',
        'common/components/toolbar/toolbar',
        'common/components/multi-select/multi-select',
        './change-avatar',
        './change-password',
        'less!app/admin/users/detail/detail'], function (angular) {

    var module = angular.defineModule('admin.users.detail');   

    // fun code here //

    return module;

}); 
警告是所有你需要的模块必须在最后返回角度模块。如果没有,那么我创建了一个“垫片”技术,您可以手动将其传递,如:

var module = angular.defineModule('admin.roles.settings', ['textAngular']);

有兴趣获得其他人的反馈…

我同意ngDefine syntax sugar(暗示我犹豫不决)。我同意你的方法是可行的,但我的应用程序的设计,使所有的模块都分为单独的角度模块也(见),所以它不仅仅是第三方模块。