AngularJS + JQuery: कोणीयज में काम करने वाली गतिशील सामग्री कैसे प्राप्त करें


84

मैं jQuery और AngularJS दोनों का उपयोग करके एक Ajax ऐप पर काम कर रहा हूं।

जब मैं jQuery के htmlफ़ंक्शन का उपयोग करके एक सामग्री को अपडेट करता हूं (जिसमें AngularJS बाइंडिंग है) , तो AngularJS बाइंडिंग काम नहीं करता है।

निम्नलिखित वह कोड है जो मैं करने की कोशिश कर रहा हूं:

$(document).ready(function() {
  $("#refreshButton").click(function() {
    $("#dynamicContent").html("<button ng-click='count = count + 1' ng-init='count=0'>Increment</button><span>count: {{count}} </span>")
  });
});
</style><script src="http://docs.angularjs.org/angular-1.0.1.min.js"></script><style>.ng-invalid {
  border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="">
  <div id='dynamicContent'>
    <button ng-click="count = count + 1" ng-init="count=0">
        Increment
      </button>
    <span>count: {{count}} </span>
  </div>


  <button id='refreshButton'>
    Refresh
  </button>
</div>

मेरे पास आईडी के साथ डिव के अंदर डायनामिक कंटेंट है #dynamicContent, और मेरे पास रिफ्रेश बटन है जो रिफ्रेश पर क्लिक करने पर इस डिव के कंटेंट को अपडेट कर देगा। वृद्धि अपेक्षित रूप से काम करती है यदि मैं सामग्री को ताज़ा नहीं करता, लेकिन ताज़ा करने के बाद, AngularJS बाइंडिंग काम करना बंद कर देती है।

यह AngularJS में मान्य नहीं हो सकता है, लेकिन मैंने शुरुआत में jQuery के साथ एप्लिकेशन बनाया और बाद में AngularJS का उपयोग करना शुरू कर दिया, इसलिए मैं AngularJS को सब कुछ माइग्रेट नहीं कर सकता। AngularJS में इस काम को पाने के लिए किसी भी मदद की बहुत सराहना की जाती है।


1
क्या इस कार्यक्षमता के लिए JQuery का उपयोग करने का कोई विशेष कारण है? जैसा कि यह अच्छी तरह से और आसानी से कोणीय द्वारा कवर किया गया है: < jsfiddle.net/pkozlowski_opensource/YCrFD/2 >
pkozlowski.opensource

3
यह समस्या दिखाने के लिए मेरे वास्तविक उपयोग के मामले का एक सरलीकृत संस्करण है। वास्तविक एप्लिकेशन में डायनामिक कंटेंट को ग्रेस टैगलिब द्वारा जेनरेट किया जाता है जिसे html के रूप में jquery को पास किया जाता है। इसलिए मैं इसे अंकुरित करने के लिए एंगुलरज के ऊपर ग्रेन टैगलिब में सभी लॉजिक को पोर्ट नहीं कर सकता।
राजा

1
@ pkozlowski.opensource, कि लिंक मर चुका है? इसके अलावा, आपको out.stackexchange.com :)
Liam

जवाबों:


115

$compileDOM में डालने से पहले आपको HTML स्ट्रिंग पर कॉल करना होगा ताकि कोणीय को बाइंडिंग करने का मौका मिले।

अपनी बेला में, यह कुछ इस तरह दिखेगा।

$("#dynamicContent").html(
  $compile(
    "<button ng-click='count = count + 1' ng-init='count=0'>Increment</button><span>count: {{count}} </span>"
  )(scope)
);

जाहिर है, $compileकाम करने के लिए इसे आपके नियंत्रक में इंजेक्ट किया जाना चाहिए।

$compileप्रलेखन में अधिक पढ़ें ।


2
धन्यवाद नूह, संकलन तब काम कर रहा है जब मैं इसे नियंत्रक विधि में करता हूं और बटन की घटना पर क्लिक करने के लिए उस नियंत्रक विधि से सीधे जुड़ जाता हूं। यहाँ काम कर रहा उदाहरण है । लेकिन मैं अपने वास्तविक ऐप में, मुझे एक अलग jquery फ़ंक्शन से नियंत्रक विधि को कॉल करना पड़ा। इसलिए मैंने ऑब्जेक्ट को स्कोप करने के लिए रेफरेंस पकड़ा और रिजेक्टाइल के लिए रिफ्रेश मेथड बुलाया, जो काम नहीं करता। यहाँ उदाहरण है । क्या आप इस उदाहरण को काम करने में मदद कर सकते हैं।
राजा

1
@ राजा जब आप कोणीय ढांचे के बाहर कोणीय तरीकों / अभिव्यक्ति को बुलाते हैं तो आपको $ स्कोप बुलाना चाहिए अपवाद को संभालने, घड़ियों को निष्पादित करने आदि का उचित गुंजाइश जीवन-चक्र करने के लिए $ apply () करना चाहिए , jsfiddle.net/fABdD/14
आर्टेम एंड्रीव

1
@ArtemAndreev बिल्कुल सही। @ राजा आप कॉल को भी फंक्शन $scope.$apply()में ले जा सकते हैं refresh()यदि यह आपके आर्किटेक्चर के लिए समझ में आता है: jsfiddle.net/nfreitas/8xkeh/1
नूह फ्रीटास

3
के लिए लिंक angular-1.0.1.min.jsमूल उदाहरण में यहाँ 404. था @ ArtemAndreev-s उदाहरण के काम कर संस्करणों अपडेट किया जाता है: jsfiddle.net/pmorch/fABdD/186 और @NoahFreitas उदाहरण: jsfiddle.net/pmorch/8xkeh/43
पीटर वी Mørch

1
एक नियंत्रक के भीतर $ संकलित और जोड़ तोड़ डोमेन का उपयोग करने से आपको अप्राप्य कोड होने का मार्ग दिखाई देगा। डोम को कभी भी नियंत्रक नहीं बदलने के लिए निर्देशों का उपयोग किया जाना चाहिए।
एनजे

57

मामले में एक और समाधान आप गतिशील सामग्री पर नियंत्रण नहीं है

यह काम करता है अगर आपने अपने तत्व को एक निर्देश के माध्यम से लोड नहीं किया है (जैसे कि टिप्पणी jsfiddles में उदाहरण की तरह)।

अपनी सामग्री लपेटें

अपनी सामग्री को एक div में लपेटें ताकि आप JQuery का उपयोग करते समय इसे चुन सकें । आप अपने तत्व को प्राप्त करने के लिए देशी जावास्क्रिप्ट का उपयोग करने का विकल्प भी चुनते हैं।

<div class="selector">
    <grid-filter columnname="LastNameFirstName" gridname="HomeGrid"></grid-filter>
</div>

कोणीय इंजेक्टर का उपयोग करें

यदि आपके पास एक नहीं है, तो आप $ संकलित करने के लिए एक संदर्भ प्राप्त करने के लिए निम्न कोड का उपयोग कर सकते हैं।

$(".selector").each(function () {
    var content = $(this);
    angular.element(document).injector().invoke(function($compile) {
        var scope = angular.element(content).scope();
        $compile(content)(scope);
    });
});

सारांश

मूल पोस्ट को लगता है कि आपके पास एक $ संकलन संदर्भ काम था। यह स्पष्ट रूप से आसान है जब आपके पास संदर्भ है, लेकिन मैंने ऐसा नहीं किया मेरे लिए यह जवाब था।

पिछले कोड का एक कैविएट

यदि आप मिनिफाइ परिदृश्य के साथ एक asp.net/mvc बंडल का उपयोग कर रहे हैं, तो आपको रिलीज़ मोड में तैनात करने पर परेशानी होगी। यह समस्या अनकाउटेड एरर के रूप में सामने आती है: [$ इंजेक्टर: अनप्र] जो कि मिनिमिफायर को कोणीय जावास्क्रिप्ट कोड के साथ गड़बड़ करने के कारण होता है।

यहाँ यह उपाय करने का तरीका है :

प्रचलित कोड स्निपेट को निम्न अधिभार के साथ बदलें।

...
angular.element(document).injector().invoke(
[
    "$compile", function($compile) {
        var scope = angular.element(content).scope();
        $compile(content)(scope);
    }
]);
...

इससे पहले कि मैं इसे एक साथ पेश करता इससे पहले मुझे बहुत दुःख हुआ।


1
उपर्युक्त कोड के रूप में धन्यवाद ने मुझे गुंजाइश के लिए काम किया और संकलन उपलब्ध होने के बारे में स्पष्टीकरण दिया। कभी-कभी आप आसान भागों को याद करते हैं :)
Abs

मुझे संकलन के बाद $ पचाना पड़ा।
नं।

2
पूर्ण जीवनसाथी, मैंने अपने कोड में कोणीय के लिए एक सशर्त जांच जोड़ी, जो इसे कोणीय ऐप में प्लग किए जाने पर सभी कोणीय अच्छाई का उपयोग करने की अनुमति देता है
LiamRyan

18

@ Jwize के जवाब में जोड़

क्योंकि angular.element(document).injector()त्रुटि दे रहा था injector is not defined , इसलिए, मैंने फ़ंक्शन बनाया है जिसे आप AJAX कॉल के बाद चला सकते हैं या जब DOM को jQuery का उपयोग करके बदल दिया जाता है।

  function compileAngularElement( elSelector) {

        var elSelector = (typeof elSelector == 'string') ? elSelector : null ;  
            // The new element to be added
        if (elSelector != null ) {
            var $div = $( elSelector );

                // The parent of the new element
                var $target = $("[ng-app]");

              angular.element($target).injector().invoke(['$compile', function ($compile) {
                        var $scope = angular.element($target).scope();
                        $compile($div)($scope);
                        // Finally, refresh the watch expressions in the new element
                        $scope.$apply();
                    }]);
            }

        }

बस नए तत्व के चयनकर्ता को पास करके इसका उपयोग करें। इस तरह

compileAngularElement( '.user' ) ; 

धन्यवाद, इसने मेरे जीवन को एक पैकेज के साथ सहेजा, जिसमें UIKit का उपयोग इसके संवादों के लिए किया गया था, जिसमें HTML एक $ स्कोप फंक्शन के अंदर मक्खी पर उत्पन्न हुआ था। एक साइड नोट के रूप में, मुझे अपनी आवश्यकताओं के अनुरूप $ लक्ष्य के चयनकर्ता को बदलना पड़ा, मेरे मामले में $ ["डेटा-एनजी-नियंत्रक]"), और $ स्कोप पर टिप्पणी करें। चूंकि यह फ़ंक्शन पहले से ही एक कोणीय कॉलबैक में कहा जाता था (इसलिए आवेदन पहले से ही हो रहा था)
zontar

@zontar आप targetइसे तर्क से लेने के माध्यम से गतिशील बना सकते हैं ।
श्यामाकवाना.उम्र
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.