2016-07-14 6 views
13

चूंकि पाचन चक्र वैरिएबल की गंदे जांच करता है, यदि 100 गुंजाइश चर हैं और यदि मैं एक चर बदलता हूं तो यह सभी चरों को देखेगा।angularjs में मैन्युअल रूप से पाचन चक्र को कैसे रोकें

मान लीजिए मेरे पास 100 गुंजाइश मॉडल चर हैं जो एक-दूसरे से स्वतंत्र हैं। यदि मैं एक चर में परिवर्तन करता हूं तो मैं अन्य सभी 99 चरों को देखना नहीं चाहता हूं। क्या इसे करने का कोई तरीका है ? यदि हां, तो कैसे?

+0

ऐसे में ऐसा कोई तरीका नहीं है, लेकिन आपत्तिजनक रूप से आपके पास {{{:: myVar}} जैसे पृष्ठ से वॉचर को कम करने के लिए बाइंडोन निर्देश हो सकता है, जो अपडेट के बाद केवल एक बार और उसके बाद मूल्य के लिए देखेगा एक मान –

+1

मैं एक बार बाध्यकारी का उपयोग नहीं कर सकता। यह चर से घड़ी को हटा देगा और मुझे दो तरह की बाध्यकारी की आवश्यकता है क्योंकि मैं इनपुट बॉक्स –

+0

के लिए एनजी-मॉडल चर का उपयोग कर रहा हूं शायद '$ watchCollection' – malix

उत्तर

20

आश्चर्य की बात यह है कि आमतौर पर यह कोई समस्या नहीं है, ब्राउज़र को हजारों बाइंडिंग के साथ भी समस्या नहीं है, जब तक कि अभिव्यक्ति जटिल न हों। how many watchers are ok to have2000 का सामान्य उत्तर है।

समाधान:

यह काफी AngularJS 1.3 के बाद से आसान है, के बाद से one-time बाइंडिंग कोर में अब कर रहे हैं।

  1. एक बार चर के बाध्यकारी।

हम द्रष्टा को रोकने के लिए एक बार बंधन (::) निर्देश का उपयोग अवांछित चर को देखने के लिए कर सकते हैं। यहां, चर केवल & पर एक बार देखेगा, इसके बाद यह उस चर को अपडेट नहीं करेगा।

  1. पाचन चक्र को मैन्युअल रूप से रोकें।

HTML:

<ul ng-controller="myCtrl"> 
    <li ng-repeat="item in Lists">{{lots of bindings}}</li> 
</ul> 

नियंत्रक कोड:

app.controller('myCtrl', function ($scope, $element) { 
    $element.on('scroll', function() { 
    $scope.Lists = getVisibleElements(); 
    $scope.$digest(); 
    }); 
}); 

$digest के दौरान, आप Lists वस्तु में परिवर्तन में केवल रुचि रखते हैं, अलग-अलग करने के लिए परिवर्तन नहीं आइटम नहीं है। फिर भी, कोणीय अभी भी परिवर्तन के लिए हर एक दर्शक से पूछताछ करेगा।

stop और pause के लिए निर्देश डाइजेस्ट:

app.directive('stopDigest', function() { 
    return { 
    link: function (scope) { 
     var watchers; 

     scope.$on('stop', function() { 
     watchers = scope.$$watchers; 
     scope.$$watchers = []; 
     }); 

     scope.$on('resume', function() { 
     if (watchers) 
      scope.$$watchers = watchers; 
     }); 
    } 
    }; 
}); 

अब, नियंत्रक कोड बदला जाना चाहिए:

<ul ng-controller="listCtrl"> 
    <li stop-digest ng-repeat="item in visibleList">{{lots of bindings}}</li> 
</ul> 

app.controller('myCtrl', function ($scope, $element) { 
    $element.on('scroll', function() { 
    $scope.visibleList = getVisibleElements(); 

    $scope.$broadcast('stop'); 
    $scope.$digest(); 
    $scope.$broadcast('resume'); 
    }); 
}); 

संदर्भ डॉक्टर:https://coderwall.com/p/d_aisq/speeding-up-angularjs-s-digest-loop

धन्यवाद।

1

यह पाचन चक्र में अनन्य/सशर्त जांच करने के लिए काफी विशिष्ट उपयोग-मामला है और मुझे नहीं लगता कि यह कोणीय कोर को फोर्किंग/हैकिंग के बिना संभव है।

मैं इस बात पर प्रतिक्रिया करता हूं कि आप $watching कैसे हैं/क्या हैं। शायद ngModelController का $viewChangeListeners$watch से अधिक उपयुक्त होगा?

5

यह एक अच्छा सवाल है और कोणीय 1.x के साथ सबसे बड़ी कमियों में से एक को हाइलाइट करता है। पाचन चक्र कैसे प्रबंधित किया जाता है इस पर थोड़ा नियंत्रण नहीं है। यह एक काला बॉक्स और बड़े अनुप्रयोगों के लिए है, यह महत्वपूर्ण प्रदर्शन मुद्दों का कारण बन सकता है। आपके द्वारा सुझाए गए कार्यों को करने के लिए कोई कोणीय तरीका नहीं है, लेकिन ऐसा कुछ है जो आपको एक ही लक्ष्य प्राप्त करने में मदद करेगा (यानी - केवल एक चीज बदलते समय पाचन चक्र का बेहतर प्रदर्शन)।

मैं bind-notifier plugin का उपयोग करने की सलाह देता हूं। मेरे पास इस परियोजना के साथ कोई संबंध नहीं है, लेकिन मैं इसे अपने स्वयं के प्रोजेक्ट के लिए उपयोग कर रहा हूं और इसके साथ बड़ी सफलता मिली है।

पीछे विचार यह है कि आप कुछ बाइंडिंग निर्दिष्ट कर सकते हैं जब केवल एक विशिष्ट घटना उठाई जाती है।

वहाँ प्लगइन का उपयोग करने के कई तरीके हैं, लेकिन यहां एक है कि मैं चाहिए प्रभावी लगता है:

एक टेम्पलेट फ़ाइल में, एक का उपयोग कर बाध्यकारी विशेष बाँध-सूचक वाक्य रचना निर्दिष्ट करें:

<div>{{:user-data-change:user.name}}</div> 
<div>{{:job-data-change:job.name}}</div> 

इन दो बाइंडिंग को अधिकांश पाचन चक्रों पर गंदे-चेक नहीं किया जाएगा जब तक उन्हें अधिसूचित नहीं किया जाता है।

अपने नियंत्रक में, जब उपयोगकर्ता डेटा में परिवर्तन, इस तरह बाइंडिंग सूचित करें:

this.refreshUserData().then(() => { 
    $scope.$broadcast('$$rebind::user-data-change'); 
}); 

(और job-data-changed के लिए समान)

इस के साथ

, user.name के लिए बाइंडिंग केवल प्रसारण पर जाँच की जाएगी ।

कुछ बातें ध्यान में रखना:

  1. यह अनिवार्य रूप से कोणीय का प्रमुख लाभ (भी यह बड़े अनुप्रयोगों के लिए कोर कमजोरी है) में से एक बाधित। दो तरह से बाध्यकारी आमतौर पर इसका मतलब है कि आपको सक्रिय रूप से अपने मॉडल में परिवर्तनों को प्रबंधित करने की आवश्यकता नहीं है, लेकिन इसके साथ, आप करते हैं। इसलिए, मैं केवल आपके आवेदन के उन हिस्सों के लिए इसका उपयोग करने की अनुशंसा करता हूं जिनमें बहुत सी बाधाएं हैं और मंदी का कारण बनता है।
  2. $emit और $broadcast स्वयं प्रदर्शन को प्रभावित कर सकते हैं, इसलिए उन्हें $scope पेड़ (scope एस के कुछ हिस्सों के साथ केवल कुछ या बच्चों के साथ) पर कॉल करने का प्रयास करें।
  3. प्लगइन का उपयोग करने के कई तरीके हैं क्योंकि दस्तावेज़ों पर एक अच्छा नज़र डालें।उपयोग पैटर्न चुनें जो आपके आवेदन के लिए सबसे अच्छा काम करता है।
संबंधित मुद्दे