Comment lier l'attribut src de l'élément <script> dans AngularJS

J'essaie de lier l'attribut src d'un élément HTML <script> à une variable dans mon contrôleur angulaire, afin que je puisse le mettre à jour depuis le contrôleur sans avoir à gérer une interface utilisateur.

Jusqu'à présent, j'ai essayé toutes ces options:

 <script type="text/javascript" ng-src="{{sourceUrl}}"></script> <script type="text/javascript" src="{{sourceUrl}}"></script> <script type="text/javascript" ng-src="sourceUrl"></script> 

Dans mon contrôleur, j'ai:

 $scope.sourceUrl = "https://<some url goes here>"; 

Lorsque vous exécutez la page dans le navigateur après que le champ $ scope.sourceUrl est réglé, il n'y a pas de requête sortante pour sourceUrl, alors je suis sûr que je fais quelque chose qui ne va pas. Des idées?

J'ai trouvé plusieurs articles sur l'attribut src de l'élément <img> , et ng-src devrait fonctionner comme ils le disent, mais je suppose que <script> est en quelque sorte différent.

Malheureusement, vous ne pouvez pas utiliser Angular de cette façon. Angular traite la page Web uniquement après la chargement et la construction de la <script> l'époque où la <script> a été traitée est une seule fois (les étiquettes de script ne sont jamais exécutées qu'une seule fois). D'autres balises telles que img changent l'aspect visuel de l'écran lorsque leurs propriétés changent après la chargement de la page … mais comme mentionné, le script n'est traité qu'une seule fois et même pendant le chargement de la page et avant que Angular ne puisse jamais contrôler.

Vous auriez pu l'ajouter dynamiquement à la fin du corps à partir du contrôleur:

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

Bien que les balises de script ne puissent être interpolées que si vous pouvez simplement ajouter d'autres balises de script.

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

Dans votre contrôleur, appuyez simplement sur d'autres objets comme {src: 'foo.js'} sur le tableau de scripts et les scripts presto, paresseux.

Voici un plongeur qui démontre ceci: http://plnkr.co/edit/6QuwuqsGoyrASk8FKmu2?p=preview

Ajout de ma solution comme réponse par la suggestion de @ 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)); 

Et l'extrait de la vue suit:

 <div id="JSObjectScript" style="display: inline" my-container /> 

Je sais que la réponse arrive tard mais voici une solution élégante et simple:

Vous devez utiliser Script Script contextuel avec $ sce.trustAsResourceUrl (valeur) .

Voir la documentation

Il ressemblerait probablement à:

Dans app.js:

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

Dans index.html:

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

L'attribut src de la balise de script sera lié à sa valeur dans Angular. Voici le résultat lorsque je lance mon webapp et lance le débogueur pour vérifier le HTML rendu:

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

Notez que le script ne sera pas exécuté si la liaison se fait après le premier chargement de la balise!