AngularJS: Como fazer o script de carga angular dentro do ng-include?

Ei eu estou construindo uma página web com angular. O problema é que já existem algumas coisas construídas sem angular e eu tenho que incluí-las também

O problema é esse.

Eu tenho algo parecido com isso no meu main.html:

  

E o meu partial.html tem algo parecido com isto

 

heading 1

E meu partial.js não tem nada a ver com angularjs. nginclude funciona e eu posso ver o html, mas não consigo ver o arquivo javascript sendo carregado em tudo. Eu sei como usar o firebug / chrome-dev-tool, mas nem consigo ver a solicitação de rede sendo feita. O que estou fazendo de errado?

Eu knwo angular tem algum significado especial para tag de script. Posso anular isso?

A resposta aceita não funcionará a partir de 1.2.0-rc1 + ( questão do Github ).

Aqui está uma correção rápida criada pelo endorama :

 /*global angular */ (function (ng) { 'use strict'; var app = ng.module('ngLoadScript', []); app.directive('script', function() { return { restrict: 'E', scope: false, link: function(scope, elem, attr) { if (attr.type === 'text/javascript-lazy') { var code = elem.text(); var f = new Function(code); f(); } } }; }); }(angular)); 

Simplesmente adicione este arquivo, carregue o módulo ngLoadScript como dependência do aplicativo e use type="text/javascript-lazy" como tipo para o script que você deseja carregar preguiçosamente em partials:

  

Resposta curta: AngularJS (“jqlite”) não suporta isso. Inclua jQuery na sua página (antes de include o Angular) e ele deve funcionar. Consulte https://groups.google.com/d/topic/angular/H4haaMePJU0/discussion

Eu tentei a abordagem do neemzy, mas não funcionou para mim usando 1.2.0-rc.3. A tag de script seria inserida no DOM, mas o caminho do javascript não seria carregado. Eu suspeito que foi porque o javascript que eu estava tentando carregar era de um domínio / protocolo diferente. Então eu peguei uma abordagem diferente, e foi isso que eu criei, usando o google maps como exemplo: ( Gist )

 angular.module('testApp', []). directive('lazyLoad', ['$window', '$q', function ($window, $q) { function load_script() { var s = document.createElement('script'); // use global document since Angular's $document is weak s.src = 'https://maps.googleapis.com/maps/api/js?sensor=false&callback=initialize'; document.body.appendChild(s); } function lazyLoadApi(key) { var deferred = $q.defer(); $window.initialize = function () { deferred.resolve(); }; // thanks to Emil Stenström: http://friendlybit.com/js/lazy-loading-asyncronous-javascript/ if ($window.attachEvent) { $window.attachEvent('onload', load_script); } else { $window.addEventListener('load', load_script, false); } return deferred.promise; } return { restrict: 'E', link: function (scope, element, attrs) { // function content is optional // in this example, it shows how and when the promises are resolved if ($window.google && $window.google.maps) { console.log('gmaps already loaded'); } else { lazyLoadApi().then(function () { console.log('promise resolved'); if ($window.google && $window.google.maps) { console.log('gmaps loaded'); } else { console.log('gmaps not loaded'); } }, function () { console.log('promise rejected'); }); } } }; }]); 

Espero que seja útil para alguém.

Isso não funciona mais a partir de 1.2.0-rc1. Veja este assunto para mais detalhes, nos quais publiquei um comentário descrevendo uma solução rápida. Eu vou compartilhar aqui também:

 // Quick fix : replace the script tag you want to load by a 
. // Then write a loadScript directive that creates your script tag and appends it to your div. // Took me one minute. // This means that in your view, instead of : // You'll have :
// And then write a directive like : angular.module('myModule', []).directive('loadScript', [function() { return function(scope, element, attrs) { angular.element('').appendTo(element); } }]);

Não é a melhor solução de todas, mas, eh, nem colocar tags de script em visualizações subseqüentes. No meu caso eu tenho que fazer isso para poder usar o Facebook / Twitter / etc. widgets.

Eu usei esse método para carregar um arquivo de script dinamicamente (dentro de um controlador).

 var script = document.createElement('script'); script.type = 'text/javascript'; script.src = "https://maps.googleapis.com/maps/api/js"; document.body.appendChild(script); 

ocLazyLoad permite carregar os scripts de forma preguiçosa nos templates / views via roteadores (por exemplo, roteador ui). Aqui é um sniplet

 $stateProvider.state('parent', { url: "/", resolve: { loadMyService: ['$ocLazyLoad', function($ocLazyLoad) { return $ocLazyLoad.load('js/ServiceTest.js'); }] } }) .state('parent.child', { resolve: { test: ['loadMyService', '$ServiceTest', function(loadMyService, $ServiceTest) { // you can use your service $ServiceTest.doSomething(); }] } }); 

Para carregar dinamicamente a recaptcha a partir de uma ui-view eu uso o seguinte método:

Em application.js :

  .directive('script', function($parse, $rootScope, $compile) { return { restrict: 'E', terminal: true, link: function(scope, element, attr) { if (attr.ngSrc) { var domElem = ''; $(element).append($compile(domElem)(scope)); } } }; }); 

Em myPartial.client.view.html :

   

Infelizmente todas as respostas neste post não funcionaram para mim. Eu continuei recebendo erro.

Falha ao executar ‘gravação’ em ‘Documento’: Não é possível gravar em um documento a partir de um script externo carregado de forma assíncrona, a menos que seja explicitamente aberto.

Descobri que isso acontece se você usar alguns widgets de terceiros (demandforce no meu caso) que também chamam arquivos JavaScript externos adicionais e tentam inserir HTML. Olhando para o console e o código JavaScript, notei várias linhas como esta:

 document.write(""); 

Eu usei arquivos JavaScript de terceiros (htmlParser.js e postscribe.js) em: https://github.com/krux/postscribe . Isso resolveu o problema neste post e corrigiu o erro acima ao mesmo tempo.

(Esta foi uma maneira rápida e suja sob o prazo apertado que tenho agora. Eu não estou confortável com o uso de biblioteca JavaScript de terceiros no entanto. Espero que alguém possa chegar a uma maneira mais limpa e melhor.)

Eu tentei usar o Google reCAPTCHA explicitamente. Aqui está o exemplo:

 // put somewhere in your index.html  

 //link function of Angularjs directive link: function (scope, element, attrs) { ... var domElem = ''; $('#your-recaptcha-element').append($compile(domElem)(scope)); }