当脚本是“有角度的$injector错误”时;动态地“;加载

Angular $injector errors when scripts are "dynamically" loaded

本文关键字:错误 动态 加载 injector 有角度的 脚本      更新时间:2023-09-26

当我在页面上动态加载脚本时,遇到了一个问题。目前,我们有两个独立的项目,一个SharePoint应用程序和一个"CDN"网站,我们在其中托管所有内容文件(js、css、图像等)。

由于这些项目被分成多个项目,我们必须在加载脚本的方式上发挥创意(确保如果我们在Sharepoint项目的开发环境中浏览,它会从CDN的开发环境加载内容)

下面是我们用来动态加载脚本标签的脚本:

    <script type="text/javascript">
        var ReferenceLoader = (function () {
            var cdnUrl = {
                'devSPDomain': 'https://devCDN/',
                'testSPDomain': 'https://testCDN/',
                'prodSPDomain': 'https://prodCDN/'
            },
            baseUrl = cdnUrl[window.location.host] || 'https://prodCDN/';
            this.InsertReference = function (sources, type) {
                sources = [].concat(sources); // make sure it's an array
                type = type || 'script'; // default to script
                switch (type.toLowerCase()) {
                    case 'script': InsertScriptReference(sources); break;
                    case 'style': InsertStyleReference(sources); break;
                    default: console.log('Invalid type supplied to ''InsertReference()''');
                }
            };
            function InsertScriptReference(sources) {
                for (var i = 0; i < sources.length; i++) {
                    var s = document.createElement('script'),
                        src = baseUrl + sources[i];
                    s.setAttribute('type', 'text/javascript');
                    s.setAttribute('src', src);
                    document.head.appendChild(s);
                }
            }
            function InsertStyleReference(sources) {
                for (var i = 0; i < sources.length; i++) {
                    var s = document.createElement('style'),
                        src = baseUrl + sources[i];
                    s.setAttribute('rel', 'stylesheet');
                    s.setAttribute('href', src);
                    document.head.appendChild(s);
                }
            }
            return this;
        })();
    </script>

然后在任何给定的页面上,我们都这样使用它:

<script type="text/javascript">
    var scripts = [
        'dist/js/plugins/chart/0.0.1/chart.min.js',
        'dist/js/shared/services/util/0.0.1/utilServices.min.js',
        'dist/js/components/home/0.0.4/home.min.js'
    ];
    ReferenceLoader.InsertReference(scripts);
</script>

现在这一切都很好,我可以在页面上看到它成功地将脚本/链接标记放在了head元素中,但我得到了一个角度注入器错误。我有110%的把握,其中包含模块的文件正在加载,如果我只是在页面上(头部或主体)直接指向它的普通脚本标记,它会正常工作。有什么想法吗?

这是一个显示问题的plunker

我通过做两件事解决了这个问题:

  • 向InsertReference添加一个回调参数,该参数被调用为元素的.onload/.onreadystatechanged事件,以便每次脚本加载完成时执行
  • 从应用程序中删除ng应用程序标记,并在加载完所有脚本文件后手动引导它

我认为请求文件的方式很好,但注入错误可能是因为文件被缩小了。您必须使用Minification安全控制器声明:

var myController = function(anyVariableName, $http) {
  //We included $scope and the $http service into our controller.
  //Since we set up the $inject attribute on our controller, it doesn't matter what variable names we use.
}
myController.$inject = ['$scope', '$http']

看看这里:http://thegreenpizza.github.io/2013/05/25/building-minification-safe-angular.js-applications/