2012-08-02 8 views
81

मैं jQuery और AngularJS दोनों का उपयोग करके अजाक्स ऐप पर काम कर रहा हूं।कोणीयजेएस + JQuery: angularjs में काम करने वाली गतिशील सामग्री कैसे प्राप्त करें

जब मैं jQuery के html फ़ंक्शन का उपयोग करके एक div की सामग्री (जिसमें 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 साथ एक div अंदर गतिशील सामग्री है और मैं एक ताज़ा करें बटन है कि सामग्री को अद्यतन होता है ताज़ा होने पर इस div का क्लिक किया जाता है। यदि मैं सामग्री को रीफ्रेश नहीं करता हूं तो वृद्धि की अपेक्षा की जाती है, लेकिन जब मैं रीफ्रेश करता हूं, तो AngularJS बाध्यकारी काम करना बंद कर देता है।

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

+1

की तरह इस कार्यक्षमता के लिए JQuery का उपयोग कर के लिए किसी विशेष कारण है? चूंकि यह अच्छी तरह से और आसानी से कोणीय द्वारा कवर किया गया है:

+3

यह समस्या दिखाने के लिए मेरे वास्तविक उपयोग मामले का एक सरलीकृत संस्करण है। वास्तविक अनुप्रयोग में गतिशील सामग्री grails taglib द्वारा उत्पन्न होती है जिसे HTML के रूप में jquery पर पारित किया जाता है। तो मैं इसे पूर्ण कोणीय बनाने के लिए angularjs पर grails taglib पर सभी तर्क बंदरगाह नहीं कर सकता। – Raja

+1

@ pkozlowski.opensource, वह लिंक मर चुका है? इसके अलावा आपको http://outdoors.stackexchange.com/ में शामिल होना चाहिए :) – Liam

उत्तर

113

आपको डीओएम में डालने से पहले HTML स्ट्रिंग पर $compile पर कॉल करने की आवश्यकता है ताकि कोणीय को बाध्यकारी करने का मौका मिले।

आपके पहेली में, यह ऐसा कुछ दिखाई देगा। इस काम करने के लिए

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

जाहिर है, $compile अपने नियंत्रक में इंजेक्शन किया जाना चाहिए।

$compile documentation में और पढ़ें।

+2

धन्यवाद नोहा, संकलन काम कर रहा है जब मैं इसे नियंत्रक विधि में करता हूं और सीधे बटन की घटना पर क्लिक करने के लिए उस नियंत्रक विधि को बांधता हूं। यहां काम कर रहा है [उदाहरण] (http://jsfiddle.net/fABdD/10/)। लेकिन मैं अपने वास्तविक ऐप में, मुझे नियंत्रक विधि को एक अलग jquery फ़ंक्शन से कॉल करना पड़ा। इसलिए मैंने स्कोप ऑब्जेक्ट के संदर्भ को पकड़ लिया और रीकंपाइल करने के लिए रीफ्रेश विधि कहा जिसे काम नहीं करता है। यहां [उदाहरण] है (http://jsfiddle.net/fABdD/12/)। क्या आप इस उदाहरण को काम करने में मदद कर सकते हैं। – Raja

+1

@राज जब आप कोणीय ढांचे के बाहर कोणीय विधियों/अभिव्यक्ति को कॉल करते हैं तो आपको उचित प्रदर्शन करने के लिए [$ scope। $ Apply()] (http://docs.angularjs.org/api/ng.$rootScope.Scope) पर कॉल करना चाहिए अपवाद हैंडलिंग का जीवन चक्र, घड़ियों को निष्पादित करना आदि। http://jsfiddle.net/fABdD/14/ –

+1

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

54

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

यह काम करता है अगर आप एक निर्देश (यानी। टिप्पणी की 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 बंडल आप मुसीबत में मिल जाएगा उपयोग कर रहे हैं जब आप को रिलीज़ मोड में तैनात। समस्या असीमित त्रुटि के रूप में आती है: [$ इंजेक्टर: unpr] जो कोणीय जावास्क्रिप्ट कोड के साथ minifier गड़बड़ाने के कारण होता है।

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

यहाँ जिस तरह से यह उपाय करने है।

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

इससे पहले कि मैंने इसे एक साथ पाई, इससे मेरे लिए बहुत दुख हुआ।

+1

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

+0

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

+2

पूर्ण जीवनसेवक, मैंने अपने कोड में कोणीय के लिए एक सशर्त चेक जोड़ा जो एक कोणीय ऐप – SMC

15

@ jwize के जवाब

क्योंकि angular.element(document).injector() त्रुटि injector is not defined तो, मैं बनाया है समारोह है कि आप AJAX कॉल के बाद चला सकते हैं या जब डोम 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') ; 
+0

"[ng-app]" में प्लग इन होने पर सभी कोणीय भलाई का उपयोग करने की अनुमति देता है, धन्यवाद – tylerlindell

+0

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