Hej, buduję stronę internetową z angular. Problem w tym, że coś jest już zbudowane bez kątowników i też muszę je uwzględnić
Problem w tym.
Mam coś takiego w moim main.html:
<ngInclude src="partial.html">
</ngInclude>
A mój Partial.html ma coś takiego
<h2> heading 1 <h2>
<script type="text/javascript" src="static/js/partial.js">
</script>
A mój Partial.js nie ma nic wspólnego z angularjs. nginclude działa i widzę html, ale nie widzę w ogóle ładowanego pliku javascript. Wiem, jak używać narzędzia firebug / chrome-dev-tool, ale nie widzę nawet wysyłanego żądania sieciowego. Co ja robię źle?
Wiem, że angular ma specjalne znaczenie dla tagu script. Czy mogę to zmienić?
Krótka odpowiedź: AngularJS ("jqlite") tego nie obsługuje. Dołącz jQuery do swojej strony (przed dołączeniem Angulara) i powinno działać. Zobacz https://groups.google.com/d/topic/angular/H4haaMePJU0/discussion
źródło
Wypróbowałem podejście neemzy, ale nie zadziałało przy używaniu 1.2.0-rc.3. Tag skryptu zostałby wstawiony do DOM, ale ścieżka javascript nie została załadowana. Podejrzewam, że to dlatego, że javascript, który próbowałem załadować, pochodzi z innej domeny / protokołu. Więc przyjąłem inne podejście i oto, co wymyśliłem, używając map Google jako przykładu: ( 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'); }); } } }; }]);
Mam nadzieję, że komuś to pomoże.
źródło
Użyłem tej metody do dynamicznego ładowania pliku skryptu (wewnątrz kontrolera).
var script = document.createElement('script'); script.type = 'text/javascript'; script.src = "https://maps.googleapis.com/maps/api/js"; document.body.appendChild(script);
źródło
To już nie zadziała od wersji 1.2.0-rc1. Zobacz ten problem, aby uzyskać więcej informacji na ten temat, w którym zamieściłem komentarz opisujący szybkie obejście. Podzielę się tym również tutaj:
// Quick fix : replace the script tag you want to load by a <div load-script></div>. // 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 : <script src="/path/to/my/file.js"></script> // You'll have : <div ng-load-script></div> // And then write a directive like : angular.module('myModule', []).directive('loadScript', [function() { return function(scope, element, attrs) { angular.element('<script src="/path/to/my/file.js"></script>').appendTo(element); } }]);
Nie jest to najlepsze rozwiązanie w historii, ale hej, też nie jest umieszczanie tagów skryptów w kolejnych widokach. W moim przypadku muszę to zrobić, aby skorzystać z Facebooka / Twittera / itp. widżety.
źródło
ocLazyLoad pozwala na leniwe ładowanie skryptów w szablonach / widokach przez routery (np. ui-router). Oto 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(); }] } });
źródło
Aby dynamicznie załadować recaptcha z a
ui-view
używam następującej metody:W
application.js
:.directive('script', function($parse, $rootScope, $compile) { return { restrict: 'E', terminal: true, link: function(scope, element, attr) { if (attr.ngSrc) { var domElem = '<script src="'+attr.ngSrc+'" async defer></script>'; $(element).append($compile(domElem)(scope)); } } }; });
W
myPartial.client.view.html
:<script type="application/javascript" ng-src="http://www.google.com/recaptcha/api.js?render=explicit&onload=vcRecaptchaApiLoaded"></script>
źródło
$(element)
dlaczego potrzebujesz$()
składni. z dokumentu ajs docs „Wszystkie odwołania do elementów w Angular są zawsze opakowane w jQuery lub jqLite” (np. argument elementu w funkcji kompilacji / link dyrektywy) - więc z tego i innych moich doświadczeń - spodziewałem się, że użyjesz elementu „. append (...) `- chociaż ostatecznie nie byłem tym, czego mogłem użyć - podczas testowania byłem zdezorientowany, gdy zobaczyłem tę część i nie działał dla mnie, gdy próbowałem pracować tylko z 'element.append' składniaNiestety wszystkie odpowiedzi w tym poście nie działają dla mnie. Ciągle otrzymywałem następujący błąd.
Dowiedziałem się, że dzieje się tak, gdy używasz widżetów innych firm (w moim przypadku popyt), które również wywołują dodatkowe zewnętrzne pliki JavaScript i próbują wstawić HTML. Patrząc na konsolę i kod JavaScript, zauważyłem wiele linii, takich jak to:
document.write("<script type='text/javascript' "..."'></script>");
Użyłem plików JavaScript innych firm (htmlParser.js i postscribe.js) z: https://github.com/krux/postscribe . To rozwiązało problem w tym poście i jednocześnie naprawiło powyższy błąd.
(To była szybka i nieprzyjemna droga w napiętym terminie, który mam teraz. Nie czuję się jednak komfortowo w korzystaniu z biblioteki JavaScript innej firmy. Mam nadzieję, że ktoś może wymyślić czystszy i lepszy sposób).
źródło
Próbowałem użyć Google reCAPTCHA jawnie. Oto przykład:
// put somewhere in your index.html <script type="text/javascript"> var onloadCallback = function() { grecaptcha.render('your-recaptcha-element', { 'sitekey' : '6Ldcfv8SAAAAAB1DwJTM6T7qcJhVqhqtss_HzS3z' }); };
//link function of Angularjs directive link: function (scope, element, attrs) { ... var domElem = '<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>'; $('#your-recaptcha-element').append($compile(domElem)(scope)); }
źródło