2015-06-19 18 views
15

प्रतिपादन करते समय स्पिनर लोड हो रहा है मेरे पास कुछ टैब वाले एक पृष्ठ हैं और प्रत्येक टैब में बड़ी संख्या में कोणीय बाइंडिंग हैं। This नमूना पृष्ठ है जहां मुझे समस्या का सामना करना पड़ रहा है। प्रत्येक टैब को प्रस्तुत करने में लगभग 10 सेकंड लगते हैं।कोणीय टैब

तो मैंने टैब रेंडर करते समय लोडिंग स्पिनर देने की योजना बनाई। इसलिए मैंने टैब पर क्लिक के दौरान लोडिंग स्पिनर दिखाने की योजना बनाई और अंत में स्पिनर को हटा दिया ($last) एनजी-दोहराना।

टैब पर एनजी क्लिक में मैं कताई लोडर

<ul> 
    <li ng-repeat="tab in tabs" 
     ng-class="{active:isActiveTab(tab.url)}" 
     ng-click="onClickTab(tab)">{{tab.title}} 
    </li> 
</ul> 

सक्रिय नियंत्रक में

$scope.onClickTab = function (tab) { 
    showLoader(); 
    $scope.currentTab = tab.url; 
} 

एनजी-दोहराने की जांच करने के पूरा हो गया है मैं निर्देश

.directive('onFinishRender', function ($timeout) {  
    return { 
     restrict: 'A', 
     link: function (scope, element, attr) { 
      if (scope.$last === true) { 

       $timeout(function() { 
        scope.$emit('ngRepeatFinished'); 
       }); 
      } 
     } 
    } 
}); 

$scope.$on('ngRepeatFinished', function (ngRepeatFinishedEvent) { 
     removeLoader(); 
}); 
नीचे का इस्तेमाल किया है

शोलोडर और निकालने वाला लोडर सरल कार्य है जो एक सरल लोडिंग स्पिन वाले div को जोड़ और हटा देता है नेर।

function showLoader() { 
    $('body').append('<div class="loader"></div>'); 
} 

function removeLoader() { 
    $('.loader').fadeOut(function() { 
     $(this).remove(); 
    }); 
} 

अपेक्षित परिणाम:। स्पिनिंग लोडर जब टैब पर क्लिक किया और एनजी-दोहराने खत्म होने तक दिखाई दिखाया जा सकता है (यानी क्लिक किया टैब पूरी तरह से renders)

वास्तविक परिणाम: लोडर नहीं दिखाया गया है उन्हें क्लिक करने पर टैब और यह लगभग ng-repaet के अंत में दिखाई देता है और सेकंड के अंश के लिए दिखाई देता है। Here आप कहा व्यवहार देख सकते हैं। मुझे लगता है कि पेज कोणीय बाइंडिंग प्रक्रिया के कारण स्पिनर को दिखाने में सक्षम नहीं है जो पेज फ्रीज बनाता है।

क्या कोई इसे हल करने में मेरी सहायता कर सकता है?

+0

मेरा उत्तर सही है क्योंकि यह डेटा बाइंडिंग के कारण लोड फ्लिकर के साथ इस सटीक मुद्दे को हल करने वाले एंगुलर के लेखक द्वारा लिखे गए एसओ थ्रेड से सोर्स किया गया है।मैंने प्रस्तावित 2 समाधानों के अलावा, मैं उन स्थानों पर 1 तरीके डेटा बाइंडिंग का उपयोग करने का भी सुझाव दे सकता हूं, जहां आपको 2 तरीके डेटा बाध्यकारी की आवश्यकता नहीं है (यदि आप अधिकतर लोगों की तरह हैं तो आपको अपने अधिकांश ऐप के माध्यम से केवल 1 तरीके डेटा बाध्यकारी की आवश्यकता है यदि सभी यह)। यह आसानी से {{:: member.name}} –

+0

कार्यशील डेमो और अधिक महत्वपूर्ण रूप से, मेरे उत्तर में जोड़ा गया सही समाधान जैसे आपके डेटा बाध्य अभिव्यक्तियों के अंदर एक डबल कोलन शामिल करके किया जा सकता है। उस बक्षीस को छोड़ दो! –

+1

मुझे लगता है कि ओपी सभी उत्तरों को पढ़ सकता है और फिर तय कर सकता है कि कौन सा व्यक्ति अपने आप से बक्षीस (यदि कोई है) पुरस्कार देता है? –

उत्तर

12

आप अपने कोड बदल सकते हैं: पेज नया स्वरूप -

आप aboout पढ़ सकते हैं कि here

इस समस्या को हल करने के लिए सिर्फ एक ही रास्ता है इस तरह:

$timeout(function() { 
    $scope.currentTab = tab.url 
}, 100); 

डेमो: http://jsfiddle.net/eRGT8/1053/

मैं क्या है, क्या मैं अगले DIGE को currentTab परिवर्तन धक्का सेंट चक्र (यह किसी प्रकार का हैक है, मुझे कोई समाधान नहीं है।) इसलिए, पहले पाचन चक्र में ($timeout से पहले) केवल लोडिंग दिखाया गया है। अगले पाचन चक्र में, अवरुद्ध ng-repeat सामान काम करना शुरू कर देता है लेकिन चूंकि हम पहले दिखाई देने वाली लोडिंग करते हैं, ऐसा प्रतीत होता है।

:)

यह आपकी समस्या नहीं सुलझती, लेकिन लंबे चल चल रहा है और जावास्क्रिप्ट कि ब्राउज़र पूरी तरह से लटका हुआ है अवरुद्ध एक अच्छा उपयोगकर्ता अनुभव नहीं है। साथ ही, चूंकि ब्राउज़र पूरी तरह से लटका हुआ है, इसलिए लोडिंग gif एनिमेट नहीं होगा, केवल दिखाई देगा।

+3

आप एनिमेटेड जीआईएफ के बजाय लोडर के लिए सीएसएस एनिमेशन का उपयोग कर सकते हैं और लोडर प्रतिपादन के दौरान भी एनिमेट कर देगा। 100 एमएमएस देरी सेट करने की कोई ज़रूरत नहीं है, बिना देरी के केवल $ टाइमआउट चाल चलेंगे। इसे जांचें: http://jsfiddle.net/v65kqygf/ – tomtastico

+0

हालांकि यह एक हैक/वर्कअराउंड का थोड़ा सा है, यह प्रस्तुति शुरू होने से पहले स्पिनर के प्रदर्शन की गारंटी के लिए सबसे आसान तरीका है। मेरे gif लॉक हो जाता है हालांकि सीएसएस स्पिनर में बदलने जा रहा है। – EdL

+0

@Umut Benzer प्रत्येक टैब में इस तरह स्पिनर दिखाना संभव है। डेमो में आपने प्रदान किया है कि यदि मैं टैब के बीच स्विच करता हूं तो यह स्क्रीन लोड होने तक स्क्रीन को फ्रीज करता है और मैं पहले से लोड होने वाले दूसरे टैब पर वापस नहीं जा सकता। मैं एक ही कार्यक्षमता की तलाश में था, बस प्रत्येक टैब में स्वतंत्र रूप से आवश्यक है ताकि मैं टैब के बीच स्वतंत्र रूप से स्विच कर सकूं। क्या आप इस पर कोई संकेत दे सकते हैं, क्या यह संभव है या नहीं। –

1

मैं आमतौर पर एनजी-अगर का उपयोग करके अपने एचटीएमएल में इसे हल करता हूं।

<ul> 
    <span ng-if="!tabs">Content loading...</span> 
    <span ng-if="tabs && tabs.length < 1">No tabs available</span> 
    <span ng-if="tabs && tabs.length > 0"> 
    <li ng-repeat="tab in tabs" 
     ng-class="{active:isActiveTab(tab.url)}" 
     ng-click="onClickTab(tab)">{{tab.title}} 
    </li> 
    </span> 
</ul> 
+0

इसने समस्या को हल नहीं किया। यहां आपके समाधान को दिखाया गया बेवकूफ है http://jsfiddle.net/eRGT8/1046/ समस्या यह है कि लोडिंग स्पिनर प्रदर्शित नहीं होता है जबकि टैब प्रतिपादन करता है। – Navaneet

+0

आपको इस तर्क को टैब की सामग्री पर लागू करना होगा :) क्षमा करें कि मैंने गलत समझा। – Carsten

+0

टैब सामग्री पर इस तर्क को लागू करके आपका क्या मतलब है? मैं तुम्हें नहीं मिला – Navaneet

1

मुझे लगता है कि यह जबकि पेज rendring लोड हो रहा है स्पिनर को दिखाने के लिए posibble नहीं है:

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

+0

पेज लोड होने पर वह लोडर के लिए नहीं पूछ रहा है, लेकिन पृष्ठ के अंदर एक टैब की सामग्री को प्रस्तुत करते समय स्पिनर के लिए (यह प्रश्न कोणीय के लिए विशिष्ट है) मुझे पूरा यकीन है कि वहां एक रास्ता होना चाहिए और मैं एक [समान समस्या] (http://stackoverflow.com/questions/30899334/loading-a-template-in-angular-routeprovider-asynchronously) –

+0

बेशक आप टेम्पलेट को असीमित रूप से लोड कर सकते हैं, लेकिन जब ब्राउज़र सामग्री प्रस्तुत करता है (कोणीय काम करता है) स्पिनर नहीं होगा किसी भी मामले में काम – Mikalai

0

आप प्रत्येक ली उदाहरण लोड हो रहा है-काउंटर के लिए कस्टम निर्देश कर सकते हैं, तो निर्भरता सेवा जोड़ने जो काउंटर का आयोजन करेगा, और लिंक समारोह के अंदर प्रत्येक निर्देश में आप कॉल कर सकते हैं

var app = angular.module('app', []); 
 

 
app.controller('List', function(LoadingCounter) { 
 

 
    this.tabs = [{ 
 
    title: "Test tab", 
 
    url: "http://google.sk" 
 
    }, { 
 
    title: "Test tab", 
 
    url: "http://google.sk" 
 
    }, { 
 
    title: "Test tab", 
 
    url: "http://google.sk" 
 
    }] 
 

 
    this.LoadingCounter = LoadingCounter; 
 

 
}); 
 

 
app.directive('spinningLoader', function(LoadingCounter) { 
 
    return { 
 
    restrict: 'A', 
 
    scope: { 
 
     max: "=" 
 
    }, 
 
    link: function(scope) { 
 
     LoadingCounter.updateCounter(scope.max); 
 
    } 
 
    } 
 
}); 
 

 
app.factory('LoadingCounter', function($timeout) { 
 
    var service = {}; 
 

 
    service.currentCounter = 0; 
 
    service.finished = false; 
 
    service.updateCounter = function(max) { 
 
    service.currentCounter++; 
 
    if (service.currentCounter == max) { 
 
     //example timeout 
 
     $timeout(function() { 
 
     service.finished = true; 
 
     }, 2000); 
 

 
    } 
 
    } 
 
    service.isFinished = function() { 
 
    return service.finished; 
 

 
    } 
 
    return service; 
 
});
.hidden { 
 
    display: none; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<body ng-app="app" ng-controller="List as _"> 
 
    <div ng-if="!_.LoadingCounter.isFinished()">Loading</div> 
 
    <ul ng-class="{'hidden' : !_.LoadingCounter.isFinished() }"> 
 
    <li spinning-loader max="_.tabs.length" ng-repeat="tab in _.tabs" ng-class="{active:isActiveTab(tab.url)}" ng-click="onClickTab(tab)">{{tab.title}} 
 
    </li> 
 
    </ul> 
 
</body>

6

मैं अंगुलरजेएस के लेखक द्वारा लिखे गए इस एसओ थ्रेड को पहले पढ़ने की सिफारिश करेंगे जो मूल समस्या को संबोधित करते हैं।

Delaying AngularJS route change until model loaded to prevent flicker

Misko तो पूछता है $ routeProvider के उपयोग का सुझाव देकर इस विषय के बारे में अपने ही सवाल का जवाब, जैसे इतना:

$routeProvider. 
     when('/phones', { 
     templateUrl: 'partials/phone-list.html', 
     controller: PhoneListCtrl, 
     resolve: PhoneListCtrl.resolve}). // <-- this is the connection when resolved 
     when('/phones/:phoneId', { 
     templateUrl: 'partials/phone-detail.html', 
     controller: PhoneDetailCtrl, 
     resolve: PhoneDetailCtrl.resolve}). 
     otherwise({redirectTo: '/phones'}); 

यहाँ तैयार उत्पाद/समाधान आप की मांग कर रहे है, जो AngularJS फोन डेमो का एक उन्नत संस्करण:

http://mhevery.github.io/angular-phonecat/app/#/phones

यह requ ires NgRoute(), लेकिन सही दृष्टिकोण है। यहां एक $ टाइमआउट का उपयोग करना मेरे लिए हैकी की तरह लगता है - मैं यह नहीं कह रहा हूं कि आपको ngRoute की आवश्यकता है, हालांकि मुझे यकीन नहीं है कि इसे बिना इसे कैसे खींचें (और मुझे एहसास है कि आपके टैब वर्तमान में रूट नहीं हो सकते हैं, लेकिन मुझे उम्मीद है कि यह किसी भी तरह से मदद करता है) ।

इसके अलावा, angular.element (दस्तावेज़) का उपयोग भी कर सकते हैं .ready (function() {}); आपके प्रारंभिक पेलोड के लिए भी आपके woahs हल करेंगे।

angular.element(document).ready(function(){ 
    $('.loading').remove(); // Just an example dont modify the dom outside of a directive! 
    alert('Loaded!'); 
}); 

जैसा कि आप कोई $ टाइमआउट (फ़ंक्शन() {}) नहीं देख सकते हैं; प्रयोग किया जाता है या तो दृष्टिकोण, यहाँ() angular.element.ready का सबूत काम करता है - एक रूटर के बिना:

श्रमजीवी डेमो http://codepen.io/nicholasabrams/pen/MwOMNR

* यदि आप reaaally मुझे जरूरत है अगर मैं कुछ टैब कर सकते हैं करने के लिए लेकिन आपने अपनी पोस्ट में एक वर्किंग कोड नमूना नहीं दिया है, इसलिए मैंने समाधान दिखाने के लिए एक और धागे के लिए बनाया एक और डेमो इस्तेमाल किया।

यहां एक और समाधान है, इस बार मैंने आपका उदाहरण इस्तेमाल किया!

http://jsfiddle.net/eRGT8/1069/

इस बार मैं एक समारोह आग जब $ सूचकांक === $ पिछले (ngRepeat() में अंतिम तत्व) इस तरह से लोडर डोम से हटा दिया या छिपा हुआ है जब दोहराने है अपने व्यवसाय को पूरा करना समाप्त कर दिया)

+0

मैं वास्तव में विश्वास नहीं कर सकता कि कितने लोग ऐप को धीमा कर रहे हैं, यह ऐप को लोड करने के लिए बस $ टाइमआउट के साथ धीमा कर रहा है। क्या उसके साथ कुछ गलत नहीं है? –

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