Angular提供的是通过ng-include动态加载具有动态名称的模板。部分内联JS和CSS将加载正常,但没有一种好方法下载动态URL脚本。我们需要下载相对于.html部分调用它们的路径的脚本。 (即我们有一个包含文件的目录,并希望.html文件声明它自己需要的脚本等。)
与在动态包含的部分中加载带有静态src的脚本的this question相反,我想包括动态创建动态包含的部分中的脚本的src,使用插值或运行它通过角度函数。
例如,我可能会动态地将部分加载到我的应用程序中,从一个目录中,其中有一些部分依赖的其他资源。我没有单独下载所有文件,而是希望将该逻辑留在局部。我意识到浏览器无法做到这一点,所以我将使用ng-src并允许Angular在这里进行繁重的工作。而不是相对于部分解析每个脚本src标记,所以我将使用函数来生成URL,如下所示:
<script type="application/javascript" ng-src="prefixUrl('myUrl.js')"></script>
我该怎么做?
答案 0 :(得分:0)
请注意,这将覆盖angular中的本机脚本指令(它会检查脚本标记中的模板)。您可以重命名该指令,但我们并不需要该功能(我们无论如何都将这些服务/指令注入到页面上新引导的应用程序中。)
这假设您有一些动态下载脚本的方法。我们使用的是$ script,但是jquery或其他什么都可以工作,只需相应地更新服务。
您可以轻松地重写脚本指令,以便在不依赖函数的情况下为url本身(通过attrs.ngSrc)添加前缀,而不是使用下面的函数prefixUrl。
我添加了一个活动&#39; WidgetContentLoaded&#39;下载所有脚本后将触发(易于更改)。
的Javascript
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);
}
}
};
});
和你的HTML
<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>