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
我该怎么做?
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