Angular + RequireJS 中的控制器和指令

Controllers and Directives in Angular + RequireJS

In this plunk 我有一个示例代码 运行 Angular + Angular UI Router + RequireJS。有两个页面,每个页面都有一个对应的控制器。如果单击视图 1,您应该会看到一个包含指令的页面。

页面加载时抛出以下异常:

Cannot read property 'controller' of undefined at at my-ctrl-1.js:3

意味着 appmy-ctrl-1.js 中未定义,即使我在 app.js 中返回它。这段代码有什么问题?

HTML

 <ul class="menu">
    <li><a href ui-sref="view1">View 1</a></li>
    <li><a href ui-sref="view2">View 2</a></li>
  </ul>

  <div ui-view></div>

main.js

require.config({

    paths: {
        'domReady': 'https://cdnjs.cloudflare.com/ajax/libs/require-domReady/2.0.1/domReady',
        'angular': 'https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min',
        "uiRouter": "https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.2/angular-ui-router"
    },

    shim: {
        'angular': {
            exports: 'angular'
        },
        'uiRouter':{
            deps: ['angular']
        }
    },

    deps: [
        'start'
    ]
});

start.js

define([
    'require',
    'angular',
    'app',
    'routes'
], function (require, angular) {
    'use strict';
    require(['domReady!'], function (document) {
        angular.bootstrap(document, ['app']);
    });
});

app.js

define([
    'angular',
    'uiRouter',
    'my-ctrl-1',
    'my-ctrl-2',
    'my-dir-1'
], function (angular) {
    'use strict';
    console.log("app loaded");
    return angular.module('app', ['ui.router']);
});

我的-ctrl-1.js

define(['app'], function (app) {
    'use strict';
    app.controller('MyCtrl1', function ($scope) {
      $scope.hello = "Hello1: ";
    });
});

问题是 app.jsmy-ctrl-1.js 之间存在循环依赖。当 RequireJS 遇到循环依赖时,它传递给模块工厂的引用将是 undefined。有很多方法可以解决这个问题。一种适用于您显示的代码的简单方法是将 my-ctrl-1.js 更改为:

define(function () {
    'use strict';

    return function (app) {
        app.controller('MyCtrl1', function ($scope) {
          $scope.hello = "Hello1: ";
        });
    };
});

app.js中:

define([
    'angular',
    'my-ctrl-1',
    'my-ctrl-2',
    'my-dir-1',
    'uiRouter',
], function (angular, ctrl1) {
    'use strict';
    console.log("app loaded");
    var app = angular.module('app', ['ui.router']);
    ctrl1(app);
    return app;
});

据推测,您必须对其他控制器执行相同的操作。

documentation 有一节讨论循环依赖和其他处理它们的方法。