Как связать атрибут <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 не будет выполняться, если привязка выполняется после первой загрузки тега!