文件夹结构(简体):
|- Libs |- angular |- some-plugin |- angular-some-plugin // Exposes an angular.module("ngSomePlugin") |- require.js |- Common |- Common.ts // Exposes an angular.module("common") |- App1 |- Controllers |- SomeController.ts |- SomeOtherController.ts |- Services |- SomeService.ts |- Main.ts |- App.ts |- App2 // same as above |- AppX // same as above |- Index.html |- Main.ts
内容:
index.html的:
// All these attributes are set dynamically server-side <body id="ng-app-wrapper" data-directory="App1" data-app-name="MyApp"> <script src="Libs/require.js" data-main="Main"></script> </body>
Main.ts:
console.log("Step 1: Main.js"); requirejs.config({ paths: { "angular": "Libs/angular/angular","common": "Common/common" },shim: { "angular": { exports: "angular" } } }); require(["angular"],(angular: angular.IAngularStatic) => { angular.element(document).ready(function() { var $app = angular.element(document.getElementById("ng-app-wrapper")); var directory = $app.data("directory"); var appName = $app.data("app-name"); requirejs.config({ paths: { "appMain": directory + "/Main" } }); require([ 'common','appMain' ],function () { console.log("Step 5: App1/Main.js loaded"); console.log("Step 6: Bootstrapping app: " + appName); angular.bootstrap($app,[appName]); }); }); });
App1中的Main.ts
console.log("Step 2: App1/Main.js"); requirejs.config({ paths: { "app": "App1/App","somePlugin": "Libs/some-plugin/some-plugin",// This is an AMD module "ngSomePlugin": "Libs/angular-some-plugin/angular-some-plugin" },shim: { "ngSomePlugin": { exports: "ngSomePlugin",deps: ["somePlugin"] } } }); define([ "app" ],() => { console.log("Step 4: App.js loaded"); });
应用1 / App.ts:
console.log("Step 3: App.js"); import SomeController = require("App1/Controllers/SomeController"); import SomeOtherController = require("App1/Controllers/SomeOtherController"); import SomeService = require("App1/Services/SomeService"); define([ "angular","ngSomePlugin" ],(angular: angular.IAngularStatic) => { // This isn't called,so obvIoUsly executed to late console.log("Defining angular module MyApp"); angular.module("MyApp",["common","ngSomePlugin"]) .controller("someCtrl",SomeController.SomeController) .controller("someOtherCtrl",SomeOtherController.SomeOtherController) .service("someService",SomeService.SomeService) ; });
这似乎打破了,与旧的错误:
未捕获错误:[$inject:nomod]模块’MyApp’不可用!您拼错了模块名称或忘记加载它.
问题1:
我在这里做错了什么?在我引导我的应用程序之前,如何确保angular.module()调用完成?
这是console.logs的输出,在那里你可以看到角度还没有定义模块angular.module(“MyApp”),所以这样做明显晚了:
UPDATE
我可以在App.ts中打开角度调用,所以它不需要任何东西(除了顶部的导入).然后如果我将App添加到App1 / Main.ts中的垫片,并在其中放置依赖关系似乎有效.这是解决这个问题的好方法吗?
UPDATE2
如果我在App.ts中使用require而不是define,它会实例化角度模块,但是在它尝试引导它之后.
问题2:
有没有办法传递自定义配置,例如Libs的目录名称?我尝试了以下似乎不起作用(Main.ts):
requirejs.config({ paths: { "appMain": directory + "/Main" },config: { "appMain": { libsPath: "Libs/" },"app": { name: appName } } });
应用1 / Main.ts:
define(["module"],(module) => { var libsPath = module.config().libsPath; requirejs.config({ paths: { "somePlugin": libsPath + "somePlugin/somePlugin" // rest of paths } }); define([ // or require([]) "app" ],() => {}); });
App.ts:
define([ "module" // others ],(module) => { angular.module(module.config().name,[]); });
但是在逻辑上,这种方式,angular.bootstrap()并不等待加载App.ts.因此角度模块尚未定义,并且无法引导.看来你不能像App1 / Main.ts那样做一个嵌套的定义?我该如何配置?
亚历山大·贝雷斯基(Alexander Beletsky)写了一篇关于将requireJS和Angular联系在一起的great article(以及为什么它值得的).在其中,我想他有你的第一个问题的答案:从另一个模块加载角度,然后进行自举呼叫.这迫使需要JS在执行任何代码之前加载这些模块的依赖关系.
假设这是你的主要
console.log("Step 1: Main.js"); requirejs.config({ paths: { "angular": "Libs/angular/angular","common": "Common/common". "mainT1": "t1/main.js" },shim: { "angular": { exports: "angular" } } });
requirejs(["app"],function(app) { app.init(); });
在t1的主要内容中,您可以使实际的应用程序一次性加载.
T1 / main.ts
define("app-name",['angular'],function(angular){ var loader = {}; loader.load = function(){ var app = angular.module("app-name",[]); return app; } return loader; }
最后,我们假设你在这里提供了一个临时文件,它带有你的app.js.在这里,您可以设置顺序来获取已经完成角度加载序列的对象.一旦完成,那么你在init()函数中调用bootstrapping.
T1 / app.js
define("app",function(require){ var angular = require('angular'); var appLoader = require('mainT1'); var app = {} app.init = function(){ var loader = new appLoader(); loader.load(); angular.bootstrap(document,["app-name"]); } }