2014-04-08 16 views
13

मैं AngularJS 1.2.15 के साथ एक पृष्ठांकन निर्देश का निर्माण करने की कोशिश कर रहा हूँ:

यह मेरे विचार है:

<input type="text" ng-model="filter.user"> 
<input type="number" ng-model="filter.limit" ng-init="filter.limit=5"> 
<ul> 
    <li ng-repeat="user in (filteredUsers = (users | orderBy:order:reverse | filter:filter.user) | limitTo: filter.limit)" ng-click="showDetails(user)"> 
    {{user.id}}/{{user.firstname}} {{user.lastname}} 
    </li> 
</ul> 
<div pagination data='filteredUsers' limit='filter.limit'></div> 

और यहाँ मेरी पृष्ठांकन निर्देश है:

app.directive('pagination', function(){ 
    return { 
    restrict: 'A', 
    templateUrl: 'partials/pagination.html', 
    scope: { 
     data: '=data', 
     limit: '=limit' 
    } 
    } 
}) 

सब कुछ अंकन निर्देश के बिना पूरी तरह से ठीक काम करता है। हालांकि जैसे ही मैं पृष्ठ लोड करता हूं, मेरे नए निर्देश के साथ मुझे $rootScope:infdig त्रुटि मिलती है जो मुझे समझ में नहीं आती है क्योंकि निर्देश अनंत डेटा में समाप्त होने वाले डेटा में हेरफेर करने के लिए कुछ भी नहीं कर रहा है।
यहां समस्या क्या है और मैं इसे कैसे हल कर सकता हूं? धन्यवाद!

अद्यतन:
यहां नियंत्रक और संसाधन हैं।
नियंत्रक:

usersModule.controller('usersController', 
    function ($scope, Users) { 
    function init(){ 
     $scope.users = Users.get(); 
    } 
    init(); 
}) 

संसाधन (एक REST API से एक सरणी के रूप में उपयोगकर्ताओं हो जाता है): http://plnkr.co/edit/9GCE3Kzf21a7l10GFPmy?p=preview
बस में टाइप करें:

app.factory('Users', function($resource) { 
    return $resource('http://myrestapi.tld/users', null,{ 
     'get': { method:'GET', isArray: true, cache: true } 
    }); 
}); 

अद्यतन 2

यहाँ एक डेमो है बाएं इनपुट में एक अक्षर (जैसे "एफ")।

+0

कृपया नियंत्रक के लिए कोड निर्दिष्ट करें ताकि लोग समस्या तक पहुंच सकें। मुझे लगता है कि उपर्युक्त निर्देश सही है। आपके नियंत्रक के साथ समस्या हो सकती है। –

+0

सरल क्लाइंट साइड पेजिनेशन - http://angulartutorial.blogspot.in/2014/03/client-side-pagination-using-angular-js.html – Prashobh

+0

@ जेनिशराबादिया मैंने उपरोक्त कोड अपडेट किया। हालांकि, मुझे नहीं लगता कि इसका मेरे नियंत्रक के साथ कुछ भी करना है ... – Horen

उत्तर

27

समस्या निर्देश के भीतर नहीं है, यह $ घड़ी के भीतर निर्देश बनाता है।

$scope.$watch("filteredUsers", function() { 
    // Directive Code... 
}); 

निम्न उदाहरण में सूचना हम इसे कैसे एक निर्देश के बिना पुन: पेश: http://plnkr.co/edit/uRj19PyXkvnLNyh5iY0j

कारण ऐसा होता है, क्योंकि आप कर रहे हैं जब आप निर्देश के लिए filteredUsers भेजने के लिए, निर्देश निम्न पंक्ति बनाता है प्रत्येक बार एक पाचन चलाने के दौरान filteredUsers बदल रहा है (चूंकि आप एनजी-दोहराव कथन में असाइनमेंट डालते हैं)। http://plnkr.co/edit/stxqBtzLsGEXmsrv3Gp6

:

$scope.$watch("users | orderBy:order:reverse | filter:filter.user", function(newVal) { 
    $scope.filteredUsers = newVal; 
}, true); 

आप यहाँ समाधान की जाँच कर सकते हैं:

यह आप देख रहे हैं और अतिरिक्त पैरामीटर 'सही' $ घड़ी के लिए साथ नियंत्रक में सरणी को छानने की सोच सकते हैं ठीक करने के लिए अतिरिक्त पैरामीटर (सत्य) के बिना $ घड़ी वस्तु के साथ एक साधारण तुलना करेगा, और चूंकि आप प्रत्येक पाचन लूप में एक नई सरणी बनाते हैं, तो ऑब्जेक्ट हमेशा अलग होगा। जब आप $ घड़ी फ़ंक्शन पर सही पैरामीटर पारित कर रहे हैं, तो इसका अर्थ यह है कि यह वास्तव में उस ऑब्जेक्ट की गहरी तुलना करेगा जो $ घड़ी को फिर से चलाने से पहले लौटाता है, भले ही आपके पास ऐसे सरणी के अलग-अलग उदाहरण हों जिनके समान डेटा हैं उन्हें बराबर मानेंगे।

+0

हां, यह समस्या को हल करने लगता है। मुझे समझ में नहीं आता कि आपके पहले उदाहरण में '$ watch()' फ़ंक्शन कुछ भी क्यों बदलता है। मैं समझता हूं कि जब फ़िल्टर लागू होते हैं या बदलते हैं तो यह ट्रिगर होता है। हालांकि '$ watch()' फ़ंक्शन किसी भी तरह से 'फ़िल्टर किए गए उपयोगकर्ता' ऑब्जेक्ट को भी कुशलतापूर्वक परिवर्तित या परिवर्तित नहीं करता है। तो अनंत लूप कैसे उत्पन्न होता है? यहां तक ​​कि यदि '$ watch()' फ़ंक्शन प्रत्येक 'पाचन' के साथ एक नई वस्तु बनाता है, तो इस ऑब्जेक्ट को नहीं बदला जाना चाहिए, है ना? अगर आप स्पष्ट कर सकते हैं तो यह बहुत अच्छा होगा - अब तक धन्यवाद! – Horen

+0

चूंकि आपके एनजी-दोहराने की स्थिति में आप परिवर्तनीय फ़िल्टर किए गए उपयोगकर्ता बनाते हैं - आपका कथन है: filteredUsers = (उपयोगकर्ता | ऑर्डर द्वारा: ऑर्डर: रिवर्स | फ़िल्टर: filter.user), इसका मतलब है कि प्रत्येक पाचन चक्र में, फ़िल्टर किए गए यूज़र को एक नया ऑब्जेक्ट संदर्भ मिलता है । जब आप $ घड़ी विधि का उपयोग करते हैं, तो यह जांचता है कि संदर्भ बदल गया है और यदि यह है, तो यह घड़ी "गंदे" को मानता है, उस पर पंजीकृत कॉलबैक विधि चलाता है और फिर पाचन लूप को फिर से चलाता है - अगले पाचन लूप फ़िल्टर किए गए उपयोगकर्ता में फिर से बदलें, इसलिए $ घड़ी कॉलबैक को फिर से बुलाया जाएगा - और यहां आपका अनंत लूप है ... – Barnash

+0

ठीक है, धन्यवाद। हालांकि, 'init()' फ़ंक्शन में '$ scope.filteredUsers' ऑब्जेक्ट को एक बार घोषित करने के लिए पर्याप्त क्यों नहीं है? मेरा मतलब है, तो कोणीय को पता होना चाहिए कि यह हमेशा एक ही वस्तु है, है ना? – Horen

0

एक त्वरित समाधान 2-तरफा बाध्यकारी के बजाय निर्देश में "मैनुअल" $watchCollection जोड़ने का है।

app.directive('pagination', function($parse){ 
    return { 
    restrict: 'A', 
    template: '', 
    scope: { 
     limit: '=limit' 
    }, 
    link: function(scope, elem, attrs) { 
     var dataExpr = $parse(attrs.data); 
     var deregister = scope.$parent.$watchCollection(dataExpr, function(val) { 
     scope.data = val; 
     }); 
     scope.$on('$destroy', deregister); 
    } 
    } 
}) 

$watchCollection पर नज़र रखता है सरणी की सामग्री, नहीं यह करने के लिए संदर्भ।

इसे here चलाएं देखें।

सामान्य शब्दों में, मैं उस तरह भाव पसंद नहीं है:

filteredUsers = (users | orderBy:order:reverse | filter:filter.user) 

अंदर देखा गया। दृश्यों को केवल $scope गुण प्रस्तुत करना चाहिए, न कि नए बनाएं।

+0

मुझे समझ में नहीं आता कि यह अलग-अलग क्षेत्र के साथ कैसे काम करता है। अलग-अलग स्कोप 'attrs.data' अभिव्यक्ति का सही ढंग से मूल्यांकन करने में सक्षम कैसे होंगे? –

+0

@ निकोलेसेसुर्डू, आप सही हैं। जब बच्चे का दायरा मर जाता है तो आपको अभिभावक के दायरे पर घड़ी को पंजीकृत करना होगा और पंजीकरण करना होगा। मैंने कोड संपादित किया। –

0

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

संबंधित मुद्दे