如何在AngularJS </script>中绑定<script>元素的src属性

时间:2014-12-05 00:18:40

标签: javascript html angularjs

我正在尝试将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>在某种程度上是不同的。

7 个答案:

答案 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)进行脚本上下文转义。

请参阅Documentation

它可能看起来像:

在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>