Here is a gist
请注意,这将覆盖 angular 中的本机脚本指令(检查脚本标签中的模板)。您可以重命名指令,但我们不需要该功能(无论如何,我们将这些服务/指令注入到页面上新启动的应用程序中)。
这假设您有某种方式可以动态下载脚本。我们正在使用 $script,但 jquery 或其他也可以使用,只需相应地更新服务即可。
您可以轻松地重写脚本指令来为 url 本身添加前缀(通过 attrs.ngSrc),而不是使用下面使用函数 prefixUrl 的内容。
我添加了一个事件“WidgetContentLoaded”(易于更改),一旦下载了所有脚本,就会触发该事件。
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>