我正在尝试将HTML src
元素的<script>
属性绑定到我的角度控制器中的变量,以便我可以从控制器更新它而无需处理任何UI。
到目前为止,我已经尝试了所有这些选项:
<script type="text/javascript" ng-src="{{sourceUrl}}"></script>
<script type="text/javascript" src="{{sourceUrl}}"></script>
<script type="text/javascript" ng-src="sourceUrl"></script>
在我的控制器中我有:
$scope.sourceUrl = "https://<some url goes here>";
在$ scope.sourceUrl设置后,在浏览器中运行页面时,没有对sourceUrl的传出请求,所以我确信我做错了。有什么想法吗?
我发现了几篇关于src
元素的<img>
属性的帖子,而ng-src
应该按照他们的说法工作,但我猜<script>
在某种程度上是不同的。
答案 0 :(得分:20)
不幸的是,你不能以这种方式使用Angular。只有在加载和构建页面之后,Angular才会对网页进行处理,这时<script>
标记已被处理一次(脚本标记只运行一次)。其他标记(例如img
)会在页面加载后更改其属性更改时的视觉外观...但如上所述,脚本仅在处理时处理,甚至在此期间处理页面加载和Angular可以获得控制之前。
答案 1 :(得分:5)
您可以在控制器内动态地将其添加到正文的末尾:
$("<script>").attr({src: $scope.sourceUrl}).appendTo("body");
答案 2 :(得分:2)
根据@ 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));
视图片段如下:
<div id="JSObjectScript" style="display: inline" my-container />
答案 3 :(得分:2)
@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;
}
答案 4 :(得分:1)
虽然脚本标签只能在您添加更多脚本标签后进行插值。
<script ng-repeat="script in scripts" ng-src="{{script.src}}"></script>
在你的控制器中,只需将更多对象(如{src: 'foo.js'}
)推送到脚本数组和presto,延迟加载脚本。
以下是一个说明这一点的Plunker:http://plnkr.co/edit/6QuwuqsGoyrASk8FKmu2?p=preview
答案 5 :(得分:1)
我知道答案来得晚,但这是一个优雅而简单的解决方案:
您必须使用 $ sce.trustAsResourceUrl(value)进行脚本上下文转义。
它可能看起来像:
在app.js中:
//Dynamic Url for Tagging
$rootScope.exUrl1 = $sce.trustAsResourceUrl(confserver.example.url);
在index.html中:
<script type="text/javascript" src="{{exUrl1}}"></script>
脚本标记的src
属性将绑定到Angular中的值。
这是我运行webapp并启动调试器以检查呈现的HTML时的结果:
<script type="text/javascript" src="http://exampleUrl.js"></script>
请注意,如果在首次加载代码后完成绑定,则不会执行该脚本!
答案 6 :(得分:0)
使用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);
}
}
用法:
<dynamic-script dynamic-script-src="vm.dynamicJsPath"></dynamic-script>