AngularJS:如何在ng-include中创建角度加载脚本?

Ran*_*dra 84 angularjs

嘿我正在构建一个有角度的网页.问题是有些东西已经没有角度而已经构建,我也必须包含它们

问题是这个.

我在main.html中有这样的东西:

<ngInclude src="partial.html">
</ngInclude>
Run Code Online (Sandbox Code Playgroud)

我的partial.html有这样的东西

<h2> heading 1 <h2>
<script type="text/javascript" src="static/js/partial.js">
</script>
Run Code Online (Sandbox Code Playgroud)

而我的partial.js与angularjs无关.nginclude工作,我可以看到HTML,但我看不到正在加载的javascript文件.我知道如何使用firebug/chrome-dev-tool,但我甚至看不到网络请求.我究竟做错了什么?

我knwo angular对脚本标记有一些特殊的意义.我可以覆盖它吗?

Pao*_*tti 101

接受的答案不适用于1.2.0-rc1 +(Github问题).

这是由endorama创建的快速修复:

/*global angular */
(function (ng) {
  'use strict';

  var app = ng.module('ngLoadScript', []);

  app.directive('script', function() {
    return {
      restrict: 'E',
      scope: false,
      link: function(scope, elem, attr) {
        if (attr.type === 'text/javascript-lazy') {
          var code = elem.text();
          var f = new Function(code);
          f();
        }
      }
    };
  });

}(angular));
Run Code Online (Sandbox Code Playgroud)

只需添加此文件,将ngLoadScript模块作为应用程序依赖项加载,并将type="text/javascript-lazy"其用作脚本的类型,您可以在partials中懒惰加载:

<script type="text/javascript-lazy">
  console.log("It works!");
</script>
Run Code Online (Sandbox Code Playgroud)

  • @Blaskovicz尝试这个:https://gist.github.com/subudeepak/9617483#file-angular-loadscript-js (9认同)
  • 如果您的脚本标记具有src属性而不是内联js,我认为这不起作用. (5认同)

Mar*_*cok 39

简短回答:AngularJS("jqlite")不支持此功能.在您的页面上包含jQuery(包括Angular之前),它应该可以工作.请参阅https://groups.google.com/d/topic/angular/H4haaMePJU0/discussion

  • 我不明白为什么这样做 - 浏览器不会自动加载注入的脚本标签吗?为什么这是jQuery或jqLit​​e关注的问题? (16认同)
  • 我在加载angularjs之前加载jquery并且它可以工作 (2认同)
  • 如果你的partial.js包含一个控制器,它是如何工作的?模板将在控制器加载之前呈现并给出错误:参数'MyController'不是函数,未定义. (2认同)
  • @sthomps,看看是否有帮助:[动态加载控制器](http://stackoverflow.com/questions/15250644/angularjs-loading-a-controller-dynamically) (2认同)

Nei*_*l S 20

我尝试过neemzy的方法,但是使用1.2.0-rc.3对我没有用.脚本标记将插入到DOM中,但不会加载javascript路径.我怀疑这是因为我试图加载的javascript来自不同的域/协议.所以我采取了不同的方法,这就是我想出来的,以谷歌地图为例:( 要点)

angular.module('testApp', []).
    directive('lazyLoad', ['$window', '$q', function ($window, $q) {
        function load_script() {
            var s = document.createElement('script'); // use global document since Angular's $document is weak
            s.src = 'https://maps.googleapis.com/maps/api/js?sensor=false&callback=initialize';
            document.body.appendChild(s);
        }
        function lazyLoadApi(key) {
            var deferred = $q.defer();
            $window.initialize = function () {
                deferred.resolve();
            };
            // thanks to Emil Stenström: http://friendlybit.com/js/lazy-loading-asyncronous-javascript/
            if ($window.attachEvent) {  
                $window.attachEvent('onload', load_script); 
            } else {
                $window.addEventListener('load', load_script, false);
            }
            return deferred.promise;
        }
        return {
            restrict: 'E',
            link: function (scope, element, attrs) { // function content is optional
            // in this example, it shows how and when the promises are resolved
                if ($window.google && $window.google.maps) {
                    console.log('gmaps already loaded');
                } else {
                    lazyLoadApi().then(function () {
                        console.log('promise resolved');
                        if ($window.google && $window.google.maps) {
                            console.log('gmaps loaded');
                        } else {
                            console.log('gmaps not loaded');
                        }
                    }, function () {
                        console.log('promise rejected');
                    });
                }
            }
        };
    }]);
Run Code Online (Sandbox Code Playgroud)

我希望它对某人有帮助.

  • 很奇怪,我在1.2.0-rc3上使用外部脚本创建了我自己的版本:)无论如何,你的版本更好了,谢谢分享这个! (4认同)

nee*_*mzy 8

这将不再适用于1.2.0-rc1.有关的更多信息,请参阅此问题,我在其中发布了一条描述快速解决方法的评论.我也会在这里分享一下:

// Quick fix : replace the script tag you want to load by a <div load-script></div>.
// Then write a loadScript directive that creates your script tag and appends it to your div.
// Took me one minute.

// This means that in your view, instead of :
<script src="/path/to/my/file.js"></script>

// You'll have :
<div ng-load-script></div>

// And then write a directive like :
angular.module('myModule', []).directive('loadScript', [function() {
    return function(scope, element, attrs) {
        angular.element('<script src="/path/to/my/file.js"></script>').appendTo(element);
    }
}]);
Run Code Online (Sandbox Code Playgroud)

不是最好的解决方案,但是,嘿,也没有在后续视图中放置脚本标签.在我的情况下,我必须这样做是为了使用Facebook/Twitter /等.小部件.


Azm*_*eer 8

我使用此方法动态加载脚本文件(在控制器内).

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = "https://maps.googleapis.com/maps/api/js";
document.body.appendChild(script);
Run Code Online (Sandbox Code Playgroud)