如何将 RequireJS 模块集成到 AngularJS 应用程序中?

How to integrate RequireJS module into AngularJS application?

我想将 RequireJS 模块集成到 AngularJS 应用程序中。您可以在下面看到示例代码。如何在我的 app.js 中从 module.js 加载 Module

编辑: 看看 我自己发布的答案。您对此有何评论?

// module.js
define('Module', [], function() {
  return {
    init: function() {
      console.log("Module created!");
    }
  };
});

// app.js
var app = angular.module('app', []);

app.controller('MainCtrl', function($scope) {
  // I want Module to be available here
  $scope.data = 'app';
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.17/require.min.js"></script>
<script src="https://code.angularjs.org/1.4.0-rc.2/angular.js"></script>

<body ng-controller="MainCtrl" ng-app="app">
  <div ng-bind="data"></div>
</body>

由于 app.js 只是一个 javascript 文件,您可以只使用

require(['Module'], function(Module) {
     Module.init();
})

将它变成一种混合应用程序?

以下是如何将 RequireJS 模块和 AngularJS 模块系统一起使用。

我已将每个 AngularJS 组件保存在单独的 require 模块中,以便您可以在需要时加载它。由于需要依赖项,RequireJS 将确保加载当前 angular 模块所需的所有其他 angular 模块。

utils.getDeps 将使用 requireJS 依赖项为当前 angular 模块自动创建 angular 模块依赖项数组。

define('listModule', ['angular', 'jquery', 'utils', 'service'], function(ng, $, utils){
    var moduleInfo = {
        moduleName: 'listModule',
        deps: utils.getDeps(arguments)
    };
    
    angular.module(moduleInfo.moduleName, moduleInfo.deps)
      .directive('list', function (){
          return {
              restrict: 'E',
              template: '<div> <ul> <li ng-repeat="item in slist"> {{ item.name }} - {{ item.car }} </li> </ul> </div>',
              controller: function($scope, service){
                  $scope.slist = service.getCustomers();
              }
          }
      });
    
    return moduleInfo;
});

define('service', ['angular', 'jquery', 'utils'], function(ng, $, utils){
    var moduleInfo = {
        moduleName: 'serviceModule',
        deps: utils.getDeps(arguments)
    };
    
    angular.module(moduleInfo.moduleName, moduleInfo.deps)
      .service('service', function (){
          this.getCustomers =  function (){
              return [
                  {
                      name: 'Jack',
                      car: 'Audi'
                  },
                  {
                      name: 'Rekha',
                      car: 'Mercedes'
                  }
              ];
          };
      });
    
    return moduleInfo;
});

define('utils', ['jquery'], function($){
    var obj = {};
    obj.getDeps = function(args){
        return  $.map(args, function (e) {
             return e && e.moduleName;
        });
    };
    return obj;
});

require.config({
    paths: {
        'jquery': 'https://code.jquery.com/jquery-1.11.3.min',
        'angular': 'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min'
    },
    shim: {
        'angular': { exports: 'angular', deps: [ 'jquery' ] },
        'jquery': { exports: 'jquery' }
    }
});

require(['angular', 'jquery', 'utils', 'listModule', 'service'], function (angular, $, utils) {
    angular.module('mainApp', utils.getDeps(arguments));
    angular.element(document).ready(function() {
      angular.bootstrap($('#main'), ['mainApp']);
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.17/require.min.js"></script>

<div id="main">
    <list></list>
</div>

目前我的解决方案是在加载所需模块后手动 bootstrap 应用程序。

// module.js
define('Module', [], function() {
  return {
    init: function(elm, data) {
      elm.innerHTML = JSON.stringify(data);
    }
  };
});

// app.js
// let it be Require app
require(['Module'], function(Module) {
  
  var app = angular.module('app', []);

  app.directive('module', function() {
    return {
      scope: {
        data: '=data'
      },
      link: function(scope, elm, attr) {      
        Module.init(elm[0], scope.data);      
      }
    }
  });

  app.controller('MainCtrl', function($scope) {
    $scope.data = {
      type: 'block'
    };
  });

  // manlually initialize
  angular.element(document).ready(function() {
    angular.bootstrap(document, ['app']);
  });
    
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.17/require.min.js"></script>
<script src="https://code.angularjs.org/1.4.0-rc.2/angular.js"></script>

<body ng-controller="MainCtrl">
  <module data="data"/>
</body>