2013-07-30 7 views
6

में लंबे समय तक चलने वाले लोड ऑपरेशन मैं काम करने की कोशिश कर रहा हूं कि लंबे समय तक चलने वाले लोड ऑपरेशन को चलाने के लिए सबसे अच्छी जगह Durandal का उपयोग कर रही है।डुरंडल

मैं क्या बता सकते हैं, डेटा लोड करने के लिए सामान्य सिफारिश ViewModel के activate विधि है, जो है जो मैं आमतौर पर में है - कुछ की तरह:

viewModel.activate = function() { 
    var loadPromise = myService.loadData(); 

    return $.when(loadPromise).then(function (loadedData) { 
     viewModel.data(data); 
    }); 
}; 

मुझे पता है कि अगर मैं नहीं लौटते यहां वादा करें, फिर आमतौर पर बाइंडिंग के साथ समस्याएं होती हैं - this question and answer indicates के रूप में।

हालांकि, activate विधि में लंबे समय तक चलने वाले लोड ऑपरेशन को निष्पादित करने से लोड ऑपरेशन पूर्ण होने पर ऐप "फ्रीज" बनाता है। उदाहरण के लिए, अगर मेरा भार अब ऐसा कुछ था?

viewModel.activate = function() { 
    // All loads return a promise 
    var firstLoad = myService.loadFirstData(); 
    var secondLoad = myService.loadSecondData(); 
    var thirdLoad = myService.loadThirdDataWhichTakesAges(); 

    return $.when(firstLoad, secondLoad, thirdLoad).then(function (one, two, three) { 
     viewModel.one(one); 
     viewModel.two(two); 
     viewModel.three(three); 
    }); 
}; 

इस परिदृश्य में, यूआरएल पृष्ठ लोड किया जा रहा है के अनुसार अपडेट कर रहा है, लेकिन पृष्ठ की सामग्री अभी भी पिछले पृष्ठ से पता चलता है (जो है जो मैं "फ्रीज़" मतलब)।

आदर्श रूप से, यह अच्छा होगा अगर यूआरएल नए पेज में बदलना चाहिए, और पेज सामग्री को भी नया पेज दिखाना चाहिए (भले ही उस पृष्ठ का डेटा अभी तक वापस नहीं किया गया हो)। फिर, जैसे-जैसे प्रत्येक लोड ऑपरेशन लौटाता है, पृष्ठ के प्रासंगिक भाग को अद्यतन मॉडल में बाध्य होने पर अपडेट किया जाना चाहिए।

क्या यह Durandal के अंदर इसे प्राप्त करने के लिए एक अनुशंसित तरीका है?

मेरे वर्तमान समाधान गेंद मारना करने के लिए लोड activate विधि में, और उसके बाद viewAttached विधि में डेटा को पॉप्युलेट है:

var loadPromise; 

viewModel.activate = function() { 
    // All loads return a promise 
    var firstLoad = myService.loadFirstData(); 
    var secondLoad = myService.loadSecondData(); 
    var thirdLoad = myService.loadThirdDataWhichTakesAges(); 

    loadPromise = $.when(firstLoad, secondLoad, thirdLoad); 

    // Don't return the promise - let activation proceed. 
}; 

viewModel.viewAttached = function() { 
    $.when(loadPromise).then(function (one, two, three) { 
     viewModel.one(one); 
     viewModel.two(two); 
     viewModel.three(three); 
    }); 
}; 

यह लगता काम करने के लिए है, लेकिन मुझे याद है पढ़ने कहीं कि viewAttached पर भरोसा करना अच्छा समाधान नहीं था। मुझे यह भी यकीन नहीं है कि दौड़ की स्थिति के लिए संभावित है या नहीं, क्योंकि मैं सक्रियण को आगे बढ़ने की अनुमति दे रहा हूं।

कोई अन्य सिफारिशें?

+0

सामान्य रूप से, मेरे एसपीए अनुप्रयोगों के लिए मैं "लोडिंग" टेक्स्ट और gif के साथ एक पारदर्शी div बना देता हूं। यह div पूरे पृष्ठ पर ओवरले किया गया है, ताकि उपयोगकर्ता फ़ीड प्राप्त कर सकें कि एप्लिकेशन कुछ करने का प्रयास कर रहा है लेकिन साथ ही साथ वे किसी अन्य चीज़ पर क्लिक करने में सक्षम नहीं होना चाहिए या कुछ पेज डेटा मैनिप्ल्यूशन नहीं करना चाहिए जबकि मेरा पृष्ठ है नेविगेट किया जा रहा है। आप एक सामान्य सेवा बना सकते हैं जो किसी भी दृश्य को नेविगेशन शुरू होने से पहले कॉल कर सकता है और नेविगेशन समाप्त होने के बाद div को हटा सकता है। – Yogesh

+0

धन्यवाद @ योगेश, मैं कुछ ऐसा ही करता हूं - हालांकि मैं पूर्ण पृष्ठ ओवरले से बचने की कोशिश करता हूं क्योंकि वे मोबाइल उपकरणों पर अच्छा प्रदर्शन नहीं करते हैं। – gerrod

उत्तर

8

आपको एक वादा वापस करने की ज़रूरत नहीं है, लेकिन उस स्थिति में आपको इसे नॉकआउट बाइंडिंग में संभालना होगा ताकि आप उन तत्वों से बंधे न हों जो अपरिभाषित हैं। आप सक्रिय रूप से उस 'वापसी' से छुटकारा पाने का प्रयास कर सकते हैं लेकिन एक प्रॉपर्टी जोड़ सकते हैं जो मॉडल अभी भी लोड हो रहा है या नहीं। कुछ इस तरह:

viewModel.isLoading = ko.observable(false); 
viewModel.activate = function() { 
    isLoading(true); 
    var loadPromise = myService.loadData(); 

    $.when(loadPromise).then(function (loadedData) { 
     viewModel.data(data); 
     isLoading(false); 
    }); 
}; 

और फिर, अपने दृश्य में, आप एक अनुभाग है कि पता चलता है जब दृश्य अभी भी लोड हो रहा है और एक कि पता चलता है जब लोड हो रहा है किया जाता है है हो सकता है।Sometinhg की तरह:

<div data-bind:"visible: isLoading()">Loading Data....</div> 
<div data-bind:"visible: !isLoading()">Put your regular view with bindings here. Loading is done so bindings will work.</div> 
+0

मुझे यकीन नहीं है कि इससे बाइंडिंग सही तरीके से लागू नहीं होने वाली समस्या को रोक देगा। 'दृश्यमान:! IsLoading()' बाल बाइंडिंग को लागू होने से नहीं रोकता है (जहां 'if' बाध्यकारी होता है क्योंकि बच्चे नोड्स को डोम से हटा दिया जाता है)। मैंने जो देखा है, उससे समस्याएं होती हैं यदि आप 'सक्रिय' कॉल और 'viewAttached' कॉल के बीच अपना दृश्य मॉडल के अवलोकन को अपडेट करते हैं। – gerrod

+0

मेरे प्रश्न को फिर से पढ़ने पर ऐसा प्रतीत होता है कि मैं जो कुछ पूछ रहा था उसमें पर्याप्त विशिष्ट नहीं था - मैं डेटा को बाध्यकारी समस्याओं से बचने का सबसे अच्छा तरीका जानना चाहता था, बजाय उपयोगकर्ता को प्रदर्शित करने का सबसे अच्छा तरीका लोड ऑपरेशन हो रहा था। तो अब मुझे आपके उत्तर की प्रकृति की बेहतर समझ है; तो मैं इसे सही के रूप में चिह्नित करूंगा! – gerrod

+0

बढ़िया! इसलिए हमें इंजन को वादा वापस करने की आवश्यकता नहीं है। –

0

आप डरंडल का किस संस्करण का उपयोग कर रहे हैं? Durandal 2.0.0pre में आपको activate में एक वादा वापस नहीं करने की अनुमति दी जाएगी ताकि दृश्य की संरचना (डेटा के बिना) तुरंत हो सके।

आप viewModel.one इत्यादि को एक मॉड्यूल में रीफैक्टरिंग पर विचार कर सकते हैं जो एक कन्स्ट्रक्टर फ़ंक्शन देता है, ताकि प्रत्येक एक, दो, तीन अपने डेटा को पुनर्प्राप्त करने के लिए जिम्मेदार होंगे। इस तरह आप पहले दो कॉल loadThirdDataWhichTakesAges पर इंतजार नहीं करना पड़ेगा। यह उन परिदृश्यों में समझ में आता है जहां एक, दो, तीन एक-दूसरे पर भारी निर्भर नहीं होते हैं।

+0

यहां समस्या यह है कि यदि एक/दो/तीन सभी 'सक्रिय' और 'व्यूएटेड' के बीच कहीं हल होते हैं, तो आप अपनी बाधाओं को तोड़ने वाली दौड़ की स्थिति के साथ समाप्त होते हैं। उस लिंक को चेक करें जिसे मैंने अपने प्रश्न में संदर्भित करने के लिए संदर्भित किया था। यद्यपि आपके उत्तर के लिए धन्यवाद! – gerrod

0

संदर्भ के लिए; मैं Durandal Google समूह पर एक समान प्रश्न पोस्ट (यदि का उपयोग कर सक्रिय करने और इस तरह से viewAttached एक ठीक विचार है को प्रभावी ढंग से पूछ) और रोब Eisenberg से जबाब मिला:

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

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