Как связать атрибут <script> element src в AngularJS

Я пытаюсь связать атрибут src элемента HTML <script> с переменной в моем контроллере angular, чтобы я мог обновить его с контроллера, не имея дело с каким-либо интерфейсом.

До сих пор я пробовал все эти опции:

<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> как-то отличается.

Ответы

Ответ 1

К сожалению, вы не можете использовать Angular таким образом. Angular обрабатывает веб-страницу только после того, как страница была загружена и построена, и в это время тег <script> обрабатывался один раз (теги script выполняются только один раз). Другие теги, такие как img, изменят внешний вид экрана при изменении их свойств после загрузки страницы... но, как уже упоминалось, script обрабатывается только один раз, и даже тогда во время и до Angular может получить контроль.

Ответ 2

Вы могли бы добавить его динамически в конец тела из контроллера:

        $("<script>").attr({src: $scope.sourceUrl}).appendTo("body");

Ответ 3

Добавление моего решения в качестве ответа на предложение @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 />

Ответ 4

Хотя теги script могут быть интерполированы только после добавления тегов script.

<script ng-repeat="script in scripts" ng-src="{{script.src}}"></script>

В вашем контроллере просто нажимайте больше объектов, таких как {src: 'foo.js'}, на массив скриптов и престо, ленивые загруженные скрипты.

Вот Plunker, который демонстрирует это: http://plnkr.co/edit/6QuwuqsGoyrASk8FKmu2?p=preview

Ответ 5

Я знаю, что ответ приходит поздно, но вот изящное и простое решение:

Вы должны использовать Script контекстное экранирование с $sce.trustAsResourceUrl(значение).

См. Документация

Вероятно, это выглядит так:

В app.js:

//Dynamic Url for Tagging
    $rootScope.exUrl1 = $sce.trustAsResourceUrl(confserver.example.url);

В index.html:

<script type="text/javascript" src="{{exUrl1}}"></script>

Атрибут src тега Script будет привязан к его значению в Angular. Вот результат, когда я запускаю свой webapp и запускаю отладчик для проверки отображаемого HTML:

<script type="text/javascript" src="http://exampleUrl.js"></script>

Обратите внимание, что Script не будет выполняться, если привязка выполняется после первой загрузки тега!