Javascript 如何在 AngularJS 中绑定 <script> 元素的 src 属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27306706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to bind <script> element's src attribute in AngularJS
提问by Arsen Y.M.
I am trying to bind the srcattribute of an HTML <script>element to a variable in my angular controller, so that I can update it from controller without dealing with any UI.
我试图将srcHTML<script>元素的属性绑定到我的 angular 控制器中的变量,以便我可以从控制器更新它而无需处理任何 UI。
So far I've tried all these options:
到目前为止,我已经尝试了所有这些选项:
<script type="text/javascript" ng-src="{{sourceUrl}}"></script>
<script type="text/javascript" src="{{sourceUrl}}"></script>
<script type="text/javascript" ng-src="sourceUrl"></script>
In my controller I have:
在我的控制器中,我有:
$scope.sourceUrl = "https://<some url goes here>";
When running the page in the browser after the $scope.sourceUrl gets set there is no outgoing request to sourceUrl, so I am sure I am doing something wrong. Any ideas?
在设置 $scope.sourceUrl 后在浏览器中运行页面时,没有对 sourceUrl 的传出请求,所以我确定我做错了什么。有任何想法吗?
I found several posts about srcattribute of <img>element, and ng-srcshould work as they say, but I guess <script>is somehow different.
我发现了几篇关于元素src属性的帖子<img>,ng-src应该像他们说的那样工作,但我想<script>有些不同。
采纳答案by Kolban
Unfortunately, you can not use Angular in this way. Angular processes the web page only after the page has been loaded and built by which time the <script>tag has been processed its one time (script tags are only ever run once). Other tags such as imgwill change the visual appearance of the screen when their properties change after the page has loaded ... but as mentioned, the script is only processed onceand even then during page load and before Angular can ever get control.
不幸的是,您不能以这种方式使用 Angular。Angular 仅在页面加载并构建后处理网页,此时<script>标记已被处理一次(脚本标记只运行一次)。其他标签(例如,img在页面加载后其属性发生更改时会更改屏幕的视觉外观……但如前所述,脚本仅处理一次,甚至在页面加载期间以及在 Angular 获得控制之前)。
回答by Houdini Sutherland
You could have added it dynamically to the end of the body from within the controller:
您可以从控制器中将其动态添加到正文的末尾:
$("<script>").attr({src: $scope.sourceUrl}).appendTo("body");
回答by Arsen Y.M.
Adding my solution as an answer per @Jonathan's suggestion.
根据@Jonathan 的建议添加我的解决方案作为答案。
(function (ng) {
// Retrieve main app module
var appModule = angular.module('appModule');
// This directive appends a child <script> element to an element with 'my-container' attribute.
// This is needed for 'src' attribute generation and script evaluation of some object after the
// page has been loaded.
appModule.directive('myContainer', ['$log', 'MvcModelService', function ($log, MvcModelService) {
return {
restrict: 'A',
scope: false,
link: function (scope, elem, attrs) {
var s = document.createElement("script");
s.type = "text/javascript";
var JSObjectName = "JSObject";
// Just a random number ...
var randomNumber = Math.floor(Math.random() * Number.MAX_VALUE);
// flowId is a UUID representing current session.
var flowId = MvcModelService.FlowId;
// Construct the url where the object contents will be loaded from:
var Url = MvcModelService.UrlPrefix + "Get" + whatever + "/" + JSObjectName +
"someOtherStuffDepending on flowId and randomNumber";
s.src = Url;
$log.info("Adding script element to MyContainer with source url: " + Url);
elem.append(s);
}
};
}]);
}(angular));
And the view snippet follows:
视图片段如下:
<div id="JSObjectScript" style="display: inline" my-container />
回答by Mikjail Salazar
@Kolban is right, anyway you can try to create the script element, add the src attr and then append it to the template. For example:
@Kolban 是对的,无论如何您都可以尝试创建脚本元素,添加 src attr,然后将其附加到模板中。例如:
var exampleController = function() {
controller.exampleController= [ '$sce',function($sce) {
//Remember to set the src as a trusted src
var trustedSrc = $sce.getTrustedUrl("www.example.com");
var scriptElement = document.createElement('script');
//Add attributes
scriptElement.setAttribute("data-size", '1220x700' );
scriptElement.setAttribute("src", trustedSrc);
//Append the srcipt to some element in the template
var elementContainer = angular.element('#elementToAppend');
elementContainer.append(scriptElement);
}]
return controllers;
}
回答by Clement Lombard
I know the answer comes late but here is an elegant and simple solution:
我知道答案来晚了,但这里有一个优雅而简单的解决方案:
You have to use the Script Contextual Escaping with $sce.trustAsResourceUrl(value).
您必须将脚本上下文转义与$sce.trustAsResourceUrl(value) 一起使用。
See Documentation
查看文档
It would probably look like :
它可能看起来像:
In app.js:
在 app.js 中:
//Dynamic Url for Tagging
$rootScope.exUrl1 = $sce.trustAsResourceUrl(confserver.example.url);
In index.html:
在 index.html 中:
<script type="text/javascript" src="{{exUrl1}}"></script>
The srcattribute of the script tag will be binded to its value in Angular.
Here is the result when I run my webapp and launch the debugger to check the rendered HTML:
src脚本标签的属性将绑定到它在 Angular 中的值。这是我运行 webapp 并启动调试器以检查呈现的 HTML 时的结果:
<script type="text/javascript" src="http://exampleUrl.js"></script>
Please note that the script will not be executed if the bind is done after the first loading of the tag !
请注意,如果在第一次加载标签后完成绑定,脚本将不会执行!
回答by Enzey
Although the script tags may only be interpolated once you can just add more script tags.
尽管脚本标签可能只能插入一次,但您可以添加更多脚本标签。
<script ng-repeat="script in scripts" ng-src="{{script.src}}"></script>
In your controller just push more objects like {src: 'foo.js'}to the scripts array and presto, lazy loaded scripts.
在您的控制器中,只需将更多对象推{src: 'foo.js'}送到脚本数组和快速加载的脚本中。
Here is a Plunker that demonstrates this: http://plnkr.co/edit/6QuwuqsGoyrASk8FKmu2?p=preview
这是一个证明这一点的 Plunker:http://plnkr.co/edit/6QuwuqsGoyrASk8FKmu2?p=preview
回答by Ivan
Solution using AngularJS directive.
使用 AngularJS 指令的解决方案。
function dynamicScript () {
return {
restrict: 'E',
scope: {
dynamicScriptSrc: '='
},
link: function(scope, element, attrs, ngModel) {
setScriptSrc(element, scope.$eval(attrs.dynamicScriptSrc));
scope.$watch('dynamicScriptSrc', src => {
setScriptSrc(element, src);
});
}
}
}
function setScriptSrc(element, src) {
if(src) {
var newScript = document.createElement("script");
newScript.type = 'text/javascript';
newScript.src = src;
element.empty();
element.append(newScript);
}
}
Usage:
用法:
<dynamic-script dynamic-script-src="vm.dynamicJsPath"></dynamic-script>

