AngularJS: एनजी-इनकॉर के अंदर कोणीय लोड स्क्रिप्ट कैसे बनाएं?


85

अरे मैं कोणीय के साथ एक वेब पेज बना रहा हूं। समस्या यह है कि कुछ कोठरियां पहले से ही कोणीय के बिना निर्मित हैं और मुझे उन्हें भी शामिल करना होगा

समस्या यह है।

मैं अपने main.html में कुछ इस तरह है:

<ngInclude src="partial.html">
</ngInclude>

और मेरे आंशिक। Html में कुछ ऐसा है

<h2> heading 1 <h2>
<script type="text/javascript" src="static/js/partial.js">
</script>

और मेरे आंशिक.जे का एंगुलरज से कोई लेना-देना नहीं है। nginclude काम करता है और मैं html देख सकता हूं, लेकिन मैं जावास्क्रिप्ट फ़ाइल को लोड होने पर नहीं देख सकता। मुझे पता है कि फायरबग / क्रोम-देव-टूल का उपयोग कैसे किया जाता है, लेकिन मैं नेटवर्क अनुरोध को देख भी नहीं सकता। मैं क्या गलत कर रहा हूं?

मुझे पता है कि स्क्रिप्ट टैग के लिए कोणीय का कुछ विशेष अर्थ है। क्या मैं इसे ओवरराइड कर सकता हूं?

जवाबों:


101

स्वीकृत उत्तर 1.2.0-rc1 + ( Github समस्या ) से काम नहीं करेगा ।

यहां एंडोरामा द्वारा बनाया गया एक त्वरित समाधान है :

/*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));

बस इस फ़ाइल को जोड़ें, ngLoadScriptअनुप्रयोग निर्भरता के रूप में लोड मॉड्यूल और type="text/javascript-lazy"स्क्रिप्ट के लिए उस प्रकार का उपयोग करें जो आप आंशिक रूप से lazily लोड करने के लिए करते हैं:

<script type="text/javascript-lazy">
  console.log("It works!");
</script>

5
मुझे नहीं लगता कि यह काम करता है यदि आपके स्क्रिप्ट टैग में इनलाइन js के बजाय एक src विशेषता है।
ब्लास्कोविकz


1
यह पूरी तरह से काम करता है, हालांकि एक और चीज है जो मुझे चाहिए। एक बार निर्देश नष्ट हो जाने के बाद मैं इसे कैसे निकालूं?
सलेरर

जब मैं आलसी स्क्रिप्ट में नियंत्रक घोषित करता हूं, तो मुझे दृश्य में नियंत्रक का संदर्भ देते समय त्रुटि हुई। तुम जानते हो क्यों?
चंगवांग झांग

यही चाल चली। मैंने इसे आंशिक रूप से लोड किए गए
टैबसेट

39

संक्षिप्त उत्तर: AngularJS ("jqlite") इसका समर्थन नहीं करता है। अपने पृष्ठ पर jQuery को शामिल करें (पहले कोणीय सहित), और यह काम करना चाहिए। Https://groups.google.com/d/topic/angular/H4haaMePJU0/discussion देखें


2
यह कैसे काम करता है अगर आपके आंशिक.जेएस में एक नियंत्रक है? नियंत्रक नियंत्रक लोड होने से पहले टेम्पलेट प्रस्तुत करेगा और एक त्रुटि देगा: तर्क 'MyController' एक फ़ंक्शन नहीं है, अपरिभाषित हो गया।
sthomps


16
मुझे समझ में नहीं आता कि यह क्यों काम करता है - क्या ब्राउज़र स्वचालित रूप से एक इंजेक्शन स्क्रिप्ट टैग को लोड नहीं करेगा? यह एक jQuery या jqLite चिंता क्यों है?
स्कॉट

मेरे लिए भी काम किया, मेरी <script> टैग की सामग्री कोणीय थी। जब मैंने jular से पहले jQuery को लोड नहीं किया, तो मेरे आंशिक रूप से नीचे और स्क्रिप्ट टैग सहित सब कुछ बहुत अजीब था।
निक रसलर

20

मैंने नीमजी के दृष्टिकोण की कोशिश की, लेकिन यह मेरे लिए 1.2.0-rc.3 का उपयोग करके काम नहीं किया। स्क्रिप्ट टैग को DOM में डाला जाएगा, लेकिन जावास्क्रिप्ट पथ को लोड नहीं किया जाएगा। मुझे संदेह है कि क्योंकि मैं जिस जावास्क्रिप्ट को लोड करने की कोशिश कर रहा था वह एक अलग डोमेन / प्रोटोकॉल से था। इसलिए मैंने एक अलग दृष्टिकोण लिया, और यह वह है जो मैं एक उदाहरण के रूप में Google मानचित्र का उपयोग करके आया था: ( 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');
                    });
                }
            }
        };
    }]);

मुझे आशा है कि यह किसी के लिए उपयोगी है।


4
अजीब, मैंने बाहरी स्क्रिप्ट के साथ 1.2.0-rc3 पर अपना संस्करण बनाया :) आपका संस्करण वैसे भी बेहतर है, इसे साझा करने के लिए धन्यवाद!
नीमजी

12

मैंने एक स्क्रिप्ट फ़ाइल को गतिशील रूप से (एक नियंत्रक के अंदर) लोड करने के लिए इस पद्धति का उपयोग किया।

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

एक अच्छा @azmeer
अली

वोट किया क्योंकि यह डायनेमिक स्क्रिप्ट लोड करने के लिए सरल और सबसे अच्छा समाधान है।
आरएलडी

8

यह 1.2.0-rc1 से अब काम नहीं करेगा। इसके बारे में अधिक जानने के लिए इस मुद्दे को देखें , जिसमें मैंने एक टिप्पणी लिखी है जिसमें त्वरित वर्कअराउंड का वर्णन किया गया है। मैं इसे यहाँ भी साझा करूँगा:

// 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);
    }
}]);

सबसे अच्छा समाधान कभी नहीं, लेकिन हे, न तो बाद के विचारों में स्क्रिप्ट टैग डाल रहा है। मेरे मामले में मुझे यह करना है कि फेसबुक / ट्विटर / आदि का उपयोग करने का आदेश है। विजेट।


4

ocLazyLoad राउटर्स (जैसे ui- राउटर) के माध्यम से टेम्प्लेट / व्यू में स्क्रिप्ट्स को लोड करने की अनुमति देता है। यहाँ एक स्निपलेट है

$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();
        }]
    }
});  

मैं इस तरह एक ही मुद्दे का सामना करना पड़ा। एंटरप्राइज़ ऐप में आपको अपने सभी मार्गों का उपयोग करना पड़ता है ताकि एनजी का उपयोग करना बेहतर हो। टैब के साथ शामिल हों लेकिन एनजी-में इसके मुद्दे भी शामिल हैं जो कि कोई निर्भरता लोड करने की सुविधा नहीं है ..
सेराक शिफरॉव

1

ui-viewनिम्नलिखित विधि का उपयोग करने वाले I से गतिशील रूप से लोड करने के लिए :

इन 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));


            }
        }
    };
});

इन myPartial.client.view.html:

 <script type="application/javascript" ng-src="http://www.google.com/recaptcha/api.js?render=explicit&onload=vcRecaptchaApiLoaded"></script>

क्या यह कोणीय मूल स्क्रिप्ट निर्देश को जोड़ या ओवरराइड करता है? और क्या उस के साथ jquery का उपयोग करना है?
जैमी

1
इसे जोड़ता है। और नहीं, कोई भी जेकरी वहां इस्तेमाल नहीं की जाती है
माइकल ड्रेपर

thx - 'no jQuery का उपयोग यहां किया गया है' -weird- $(element)आपको $()सिंटैक्स की आवश्यकता क्यों है । ajs डॉक्स से 'कोणीय में सभी तत्व संदर्भ हमेशा jQuery या jqLite के साथ लिपटे रहते हैं' (जैसे कि निर्देश के संकलन / लिंक फ़ंक्शन में तत्व तर्क) - इसलिए उससे और मेरे अन्य अनुभवों से - मैं आपसे 'तत्व का उपयोग करने की अपेक्षा कर रहा था। append (...) `- हालांकि मैंने अंत में वह नहीं किया जो मैं अंत में उपयोग कर सकता था - जब Iwas का परीक्षण करते समय मैंने उस भाग को देखा और मेरे लिए काम नहीं किया जब मैंने केवल 'element.append' के साथ काम करने की कोशिश की वाक्य रचना
जेमी

doh हाँ यह है, लेकिन आप इसे angular.element () के साथ बदल सकते हैं यदि आप चाहते हैं, तो सबसे अधिक संभावना है।
माइकल ड्रेपर

0

दुर्भाग्य से इस पोस्ट में सभी जवाब मेरे लिए काम नहीं किया। मैं निम्नलिखित त्रुटि प्राप्त करता रहा।

'डॉक्यूमेंट' पर 'लिखने' को अंजाम देने में विफल: असंगत रूप से भरी हुई बाहरी स्क्रिप्ट से किसी डॉक्यूमेंट में लिखना संभव नहीं है, जब तक कि इसे स्पष्ट रूप से खोला न जाए।

मुझे पता चला कि ऐसा तब होता है जब आप कुछ 3 पार्टी विजेट (मेरे मामले में मांग) का उपयोग करते हैं जो अतिरिक्त बाहरी जावास्क्रिप्ट फ़ाइलों को कॉल करते हैं और HTML सम्मिलित करने का प्रयास करते हैं। कंसोल और जावास्क्रिप्ट कोड को देखते हुए, मैंने इस तरह कई लाइनें देखीं:

document.write("<script type='text/javascript' "..."'></script>");

मैंने 3 पार्टी जावास्क्रिप्ट फ़ाइलों (htmlParser.js और postscribe.js) का उपयोग किया: https://github.com/krux/postscribe । इससे इस पोस्ट में समस्या हल हो गई और एक ही समय में उपरोक्त त्रुटि ठीक हो गई।

(मेरे पास अभी जो तंग समय सीमा है, उसके तहत यह एक त्वरित और गंदा तरीका था। मैं हालांकि 3rd पार्टी जावास्क्रिप्ट लाइब्रेरी का उपयोग करने में सहज नहीं हूं। मुझे उम्मीद है कि कोई व्यक्ति क्लीनर और बेहतर तरीके से आ सकता है।)


0

मैंने Google reCAPTCHA का स्पष्ट रूप से उपयोग करने का प्रयास किया। यहाँ उदाहरण है:

// 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));
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.