Javascript 角度脚本加载:如何在一次调用中包含所有脚本

Javascript 角度脚本加载:如何在一次调用中包含所有脚本,javascript,angularjs,Javascript,Angularjs,我试图创建一个脚本,其中包含使我的Angular应用程序工作所需的所有脚本,但似乎无法工作: function include(destination) { var e = window.document.createElement('script'); e.setAttribute('src', destination); window.document.body.appendChild(e); } include('../Scripts/myApp/main.js'

我试图创建一个脚本,其中包含使我的Angular应用程序工作所需的所有脚本,但似乎无法工作:

function include(destination) {
    var e = window.document.createElement('script');
    e.setAttribute('src', destination);
    window.document.body.appendChild(e);
}

include('../Scripts/myApp/main.js');
include('../Scripts/myApp/appConfig.js');
include('../Scripts/myApp/MyAppController.js');
include('../Scripts/myApp/Service1.js');
include('../Scripts/myApp/Service2.js');
不幸的是,如果我尝试包含这样的应用程序脚本(顺便说一句,它们可以完美地加载到页面中),我会得到一个错误,因为angular检测到我的“ng app='myAppName'”指令,但没有找到为它声明的模块(我想是因为angular检查时脚本还没有加载)。如果我尝试至少将模块实例化放在HTML页面(main.js)直接调用的脚本上,那么它会抱怨控制器、服务等不存在,如果我将它们附加到应用程序自己的文件(app.controller()、app.factory,…)中,它不会抱怨,但也不会发生

看起来以这种方式加载脚本会使Angular无法执行它们,因为它们可能加载得太晚或其他原因。唯一的方法是设置一个脚本标记,调用HTML上的脚本

但我有种感觉,我错过了一些东西,有一种方法可以做到这一点,但我就是看不到

有人知道如何通过调用其中一个来加载所有必需的脚本吗?angular应用程序配置中是否有可以设置的内容

它看起来太脏了,不能打这么多电话,而且性能也很差

我已经检查过有一个叫做Yeoman的东西,但它看起来太大了,不符合我的要求,然后我看到了RequireJS,但我不确定这是我真正想要的,我也不确定我是否要为这个安装另一个库。最后,我在app config上看到,你可以设置在哪里可以找到视图,甚至可以设置加载控制器的方式(我想,我现在不确定什么,因为我的头太晕了),所以我想Angular可能已经做了一些事情,看起来很自然,将脚本加入其中

非常感谢。

如果您正在使用AngularJS(或任何类似的高级框架),那么绝对是时候学习模块加载了。当您开始构建更多的模块并开始处理更复杂的依赖链时,注入
标记很快就会变得站不住脚

这是一个很棒的包,可以在阳光下做任何事情。这是一个看起来不错的。是一个类似的库,允许您使用NPM管理依赖项。它比RequireJS稍微简单一点,这可能对您有好处。这是一个例子

RequireJS和Browserify都提供了命令行构建工具,它们非常棒,因为当您准备将应用程序部署到服务器时,它们可以将您的所有源代码合并到一个文件中

然而,我应该警告你,这件事并不容易。学习曲线相当陡峭。不过,这很可能是您迟早需要学习的东西。

如果您使用的是AngularJS(或任何类似的高级框架),那么您肯定是时候学习模块加载了。当您开始构建更多的模块并开始处理更复杂的依赖链时,注入
标记很快就会变得站不住脚

这是一个很棒的包,可以在阳光下做任何事情。这是一个看起来不错的。是一个类似的库,允许您使用NPM管理依赖项。它比RequireJS稍微简单一点,这可能对您有好处。这是一个例子

RequireJS和Browserify都提供了命令行构建工具,它们非常棒,因为当您准备将应用程序部署到服务器时,它们可以将您的所有源代码合并到一个文件中


然而,我应该警告你,这件事并不容易。学习曲线相当陡峭。不过,这很可能是你迟早需要学习的东西。

这是因为你的脚本是异步加载的,angular在加载页面时同步编译文档(因为我假设angular.js在脚本中,因为我没有看到上面的内容)。在这种情况下,您必须手动引导应用程序,就像使用RequireJS时一样。这里有一个例子。。。因为您没有使用像RequireJS这样的库,所以我还放置了一个hacky计数器,以查看您的所有脚本何时加载到回调,以及何时加载了所有脚本时的引导:

function include(destination) {
    var e = window.document.createElement('script');
    e.setAttribute('src', destination);
    //IE detect when script has fully loaded... Increase number of loaded scripts and
    //call bootstrap if all have loaded.
    e.onreadystatechange = function () {
        if (newjs.readyState === "loaded" || newjs.readyState === "complete") {
            e.onreadystatechange = null;
            loadedScripts++;
        }

        if (loadedScripts === numScripts) {
            bootstrapAngular("myAppName");
        }
    }

    //Other browsers. Same logic as above - Increase scripts loaded and call bootstrap when complete
    e.onload = function () {
        loadedScripts++;
        if (loadedScripts === numScripts) {
            bootstrapAngular("myAppName");
        }
    }
    window.document.body.appendChild(e);
}

//5 scripts being loaded
var numScripts = 5;
//0 currently loaded
var loadedScripts = 0;
include('../Scripts/myApp/main.js');
include('../Scripts/myApp/appConfig.js');
include('../Scripts/myApp/MyAppController.js');
include('../Scripts/myApp/Service1.js');
include('../Scripts/myApp/Service2.js');

function bootstrapAngular(appName) {
    //Assuming you are putting ng-app at document level... Change to be your specific element.
    angular.bootstrap(document, [appName]);
}
上面的解决方案有点麻烦,因为我们正在跟踪所有已加载的脚本。这就是像RequireJS这样的库可以很好地发挥作用的地方,因为它会在加载您想要的脚本时调用您的回调函数。例如:

require(['angular', 'jquery', 'appConfig', 'MyAppController', 'Service1', 'Service2'], function (ng, $) {
    //bootstrap when all is ready
    $(function () {
        ng.bootstrap(document, ["myAppName"]);
    });
});

这是因为您的脚本是异步加载的,angular在加载页面时同步编译文档(因为我假设angular.js在脚本包含中,因为我上面没有看到它)。在这种情况下,您必须手动引导应用程序,就像使用RequireJS时一样。这里有一个例子。。。因为您没有使用像RequireJS这样的库,所以我还放置了一个hacky计数器,以查看您的所有脚本何时加载到回调,以及何时加载了所有脚本时的引导:

function include(destination) {
    var e = window.document.createElement('script');
    e.setAttribute('src', destination);
    //IE detect when script has fully loaded... Increase number of loaded scripts and
    //call bootstrap if all have loaded.
    e.onreadystatechange = function () {
        if (newjs.readyState === "loaded" || newjs.readyState === "complete") {
            e.onreadystatechange = null;
            loadedScripts++;
        }

        if (loadedScripts === numScripts) {
            bootstrapAngular("myAppName");
        }
    }

    //Other browsers. Same logic as above - Increase scripts loaded and call bootstrap when complete
    e.onload = function () {
        loadedScripts++;
        if (loadedScripts === numScripts) {
            bootstrapAngular("myAppName");
        }
    }
    window.document.body.appendChild(e);
}

//5 scripts being loaded
var numScripts = 5;
//0 currently loaded
var loadedScripts = 0;
include('../Scripts/myApp/main.js');
include('../Scripts/myApp/appConfig.js');
include('../Scripts/myApp/MyAppController.js');
include('../Scripts/myApp/Service1.js');
include('../Scripts/myApp/Service2.js');

function bootstrapAngular(appName) {
    //Assuming you are putting ng-app at document level... Change to be your specific element.
    angular.bootstrap(document, [appName]);
}
上面的解决方案有点麻烦,因为我们正在跟踪所有已加载的脚本。这就是像RequireJS这样的库可以很好地发挥作用的地方,因为它会在加载您想要的脚本时调用您的回调函数。例如:

require(['angular', 'jquery', 'appConfig', 'MyAppController', 'Service1', 'Service2'], function (ng, $) {
    //bootstrap when all is ready
    $(function () {
        ng.bootstrap(document, ["myAppName"]);
    });
});

非常感谢,我一直在研究RequireJS,它看起来真的像我正在寻找的,另一个答案也很好,但它看起来像RequireJS是前进的方向。非常感谢,我一直在研究RequireJS,它看起来真的像我正在寻找的,另一个答案也很好,但是看起来需要使用RequireJS。非常感谢这个例子,它确实很好,但我最终会尝试使用RequireJS,因为它看起来更加灵活和标准化,以防我们得到更多