RequireJS 正在加载 angular 应用,但未创建 app.controller

RequireJS is loading angular app, but doesn't create app.controller

我已经设置了一个非常基本的环境,用于使用 RequireJS 加载 AngularJS 组件(由 Bower 管理)。 我的 index.html 非常基础:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Angular Resource Test</title>
</head>
<body>

    <div ng-controller="MyCtrl">
        <ul>
            <!-- this template is not populated -->
            <li ng-repeat="item in items">{{item}}</li>
        </ul>
    </div>

    <script type="text/javascript" src="bower_components/requirejs/require.js" data-main="scripts/main"></script>
</body>
</html>

我的 RequireJS 都在 main.js 中,看起来像这样:

requirejs.config({
    baseUrl: 'bower_components',
    paths: {
        'angular': '../bower_components/angular/angular',
        'angular-resource': '../bower_components/angular-resource/angular-resource'
    },
    shim: {
        'angular': {
            exports: 'angular'
        },
        'angular-resource': {
            deps: ['angular'],
        }
    },
});

define("app", ["angular", "angular-resource"], function(angular) {
    var app = angular.module('MyApp', ['ngResource']);
    return app;
});

require(["app"], function(app) {
    console.log(app); // this works
    app.controller("MyCtrl", ['$scope', '$resource',
        function($scope, $resource) {
            console.log("hello"); // this doesn't work
            $scope.items = [1, 3, 4, 5];
        }
    ]);
});

似乎所有依赖项都已解析并加载,Angular 应用程序正在实例化。但是,我无法注册 Angular 控制器。 回调函数里面的console.log()语句没有执行,好像控制器创建完全失败了?

/编辑:

ng-app 指令添加到 <body> 会产生此错误:

Uncaught Error: [$injector:modulerr] Failed to instantiate module MyApp due to: Error: [$injector:nomod] Module 'MyApp' 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.

You can find the complete project on GitHub,如果这样更清楚。

您的代码中有几处 should/may 需要更正。

  • 失踪 angular.bootstrap(document, ['MyApp']);。因为当你使用 requireJS 时,angular.bootstrap() 是一个需要。不是 angular 在脚本加载时正确初始化,而是先获取初始化。这会导致您的应用程序崩溃。为了让它工作,你需要等待 require init => 然后它会加载 angular 并初始化 angular => 一切都完成后,bootstrap 你的应用程序。
  • define() 应该包装 module/file
  • 的所有代码
  • require() 用于调用 module/file.
  • RequireJS 用于将模块分离到文件中。因此,如果您配置得当,它将更易于管理,并可能缩短应用程序的加载时间。通过将许多模块放入文件中。你刚刚破坏了 requireJS 的使用目的。 (例如,我构建了一个应用程序,其代码、插件和 html 的总量约为 3MB。但在第一页加载时,它只有 400kb,很酷吧?)

您可以尝试以下操作:

requirejs.config({
    baseUrl: 'bower_components',
    paths: {
        'angular': '../bower_components/angular/angular',
        'angular-resource': '../bower_components/angular-resource/angular-resource',
        'app' : '../scripts/app' // 'app' is the module name. It got defined by define() block, and  can be loaded by either require() or define() block
    },
    shim: {
        'angular': {
            exports: 'angular'
        },
        'angular-resource': {
            deps: ['angular'],
        }
    },
});



require(["app"], function(app) {
    console.log(app);
    app.controller("MyCtrl", ['$scope', '$resource',
        function($scope, $resource) {
            console.log("hello"); // this doesn't work
            $scope.items = [1, 3, 4, 5];
        }
    ]);

    angular.bootstrap(document, ['MyApp']);
});

在你的app.js

里面
define(["angular", "angular-resource"], function(angular) {
    var app = angular.module('MyApp', ['ngResource']);
    return app;
});

您已加载 angular,但尚未 bootstrap 由于您动态加载脚本,因此不能使用 ng-app 属性 所以你需要打电话

angular.bootstrap(document.body, ['app']);

https://docs.angularjs.org/api/ng/function/angular.bootstrap