使用Angular下载带有动态src的脚本

问题描述 投票:2回答:1

Angular提供了通过ng-include动态加载具有动态名称的模板的方法。部分内联JS和CSS将加载正常,但没有一种好方法下载动态URL脚本。我们需要下载相对于.html部分调用它们的路径的脚本。 (即我们有一个包含文件的目录,并希望.html文件声明它自己需要的脚本等)。

this question相反,<script type="application/javascript" ng-src="prefixUrl('myUrl.js')"></script> 在动态包含的部分中加载带有静态src的脚本,我想包括动态创建脚本的动态包含部分的src,使用插值或运行它和角度函数。

例如,我可能会动态地将部分加载到我的应用程序中,从一个目录中,其中有几个部分依赖的其他资源。我没有单独下载所有文件,而是希望将该逻辑留在局部。我意识到浏览器不能这样做,所以我将使用ng-src并允许Angular在这里进行繁重的工作。而不是解析相对于partial的每个脚本src标记,所以我将使用一个函数来生成url,如下所示:

Here is a gist

我该怎么做?

javascript angularjs lazy-loading
1个回答
0
投票

angular.module('myApp') .run(function ($rootScope) { $rootScope.mixin = function(urls) { if (angular.isUndefined(urls) || urls == '') { return $q.when('no mixin url'); } var deferred = $q.defer(); //timeout our requests at 5 seconds var timeoutPromise = $timeout(function() { deferred.reject(null) }, 5000); //assume that $script or some other way of downloading scripts is present $script(urls, function() { $timeout.cancel(timeoutPromise); $rootScope.$safeApply(deferred.resolve(urls)); }); return deferred.promise; }; $document.on('WidgetContentLoaded', function () { //put more interesting logic here... this is like $(document).ready() but for your included partial console.log('yay we loaded your scripts'); }); }) .service('lazyScripts', ['$q', '$timeout', '$document', function ($q, $timeout, $document) { var promises = []; this.register = function (url) { promises.push($clotho.extensions.mixin(url)); }; $timeout(function() { $q.all(promises).then(function() { //broadcast event $document.triggerHandler('WidgetContentLoaded'); }) }); }]) .directive('script', function($parse, $rootScope) { return { restrict: 'E', terminal: true, compile: function(element, attr) { if (attr.ngSrc) { var scriptUrl = $parse(attr.ngSrc)($rootScope); lazyScripts.register(scriptUrl); } } }; });

请注意,这将覆盖angular中的本机脚本指令(它检查脚本标记中的模板)。您可以重命名该指令,但我们不需要该功能(我们无论如何都将这些服务/指令注入到页面上新引导的应用程序中)。

这假设您有一些动态下载脚本的方法。我们正在使用$ script,但是jquery或其他什么都可以工作,只需相应地更新服务。

使用函数prefixUrl而不是使用下面的内容,您可以轻松地重写脚本指令,以便在不依赖函数的情况下为url本身(通过attrs.ngSrc)添加前缀。

我添加了一个事件'WidgetContentLoaded'(易于更改),一旦下载了所有脚本,它就会触发。

使用Javascript

<script type="application/javascript" ng-src="prefixUrl('inlineCalledScript.js')"></script>

<style type="text/css">
    .greenListItem {
        color: #44bb44;
    }
</style>

<ul>
    <li>This is a dynamically loaded template.</li>
    <li>Note that angular must already be bootstrapped, with the new script directive above. This will not work in your index.html file</li>
    <li class="greenListItem">Inline CSS works!</li>
</ul>

<!-- this would work without problems -->
<div ng-include="prefixUrl('anotherPartial.html')"></div>

还有你的HTML

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.