आज, Sencha विकास टीम ने अपने पुस्तकालय: ShopStyle के आधार पर एक नया डेमो एप्लिकेशन जारी करने की घोषणा की। ShopStyle एक क्लासिक iPhone और iPad ऐप है जो पॉपसुगर पोर्टल का हिस्सा है। प्रस्तुत एप्लिकेशन Sencha टच लाइब्रेरी पर विकसित किया गया था और नवाचारों में से एक का उपयोग करता है: टच कैरोसेल। विशेष रूप से, "अंतहीन हिंडोला" प्रस्तुत किया गया है, जो नई सुविधाओं में से एक है जो स्नेहा टच का हिस्सा है। इस घटक की सबसे महत्वपूर्ण विशेषता सक्रिय डोम प्रबंधन है, जो एप्लिकेशन को आईपैड पर मौजूद मेमोरी सीमा में फिट होने की अनुमति देता है।
बेशक, आप साइट पर स्रोत कोड का अध्ययन कर सकते हैं, और इस लेख में इस एप्लिकेशन को बनाने में सबसे दिलचस्प तकनीकी बिंदुओं पर विचार किया जाएगा। मुख्य समस्या यह है कि हजारों उत्पाद एक श्रेणी में हो सकते हैं। एक बार में सभी डेटा को ब्राउज़र मेमोरी में डाउनलोड करना एक गारंटीकृत फ़ाइल है।
एक हिंडोला बनाना
एक हिंडोला एक स्लाइडिंग देखने वाले क्षेत्र का उपयोग करके हजारों वस्तुओं को संभाल सकता है जो डेटा प्रदर्शित करता है। सामग्री वाले तीन क्षेत्र वर्तमान पृष्ठ के लिए बनाए गए हैं: वर्तमान, पिछला और अगला। जब उपयोगकर्ता संबंधित क्षेत्रों से फ़्लिप कर रहा होता है, तो उन्हें बनाया और नष्ट कर दिया जाता है, जो यह सुनिश्चित करता है कि सामग्री वर्तमान स्थिति से मेल खाती है। इसके कारण, यह सुनिश्चित करना संभव है कि हिंडोला में किसी भी समय तत्वों की एक निश्चित संख्या कम है, इस तथ्य के बावजूद कि उनकी वास्तविक संख्या बहुत बड़ी हो सकती है। नीचे दिए गए आरेख में, स्लाइडिंग क्षेत्र में तीन पृष्ठ होते हैं। तीसरे पेज को शुरू में फोकस किया गया है और दूसरे से चौथे पेज को इनिशियलाइज़ किया गया है। जब उपयोगकर्ता चौथे पृष्ठ पर जाता है, तो सक्रिय क्षेत्र को दाईं ओर स्थानांतरित किया जाता है, और दूसरा पृष्ठ भी हटा दिया जाता है और पांचवां बनाया जाता है।
हिंडोला का आरंभिक तत्व प्रारंभिक है। आइटम पैरामीटर का सीधे उपयोग करने के बजाय, createItem परिभाषित किया गया है जो फ़ंक्शन को स्वीकार करता है। जब तत्व को इनिशियलाइज़ करना आवश्यक होगा, तो तत्व के सूचकांक के साथ एक फ़ंक्शन को बुलाया जाएगा। फ़ंक्शन एक तत्व बनाता है और वापस करता है। इसे समझने के लिए, एक नियमित और अनंत हिंडोला के साथ कोड का एक छोटा सा टुकड़ा प्रदान किया जाता है।
// Normal carousel
var carousel = new Ext.Carousel({
items: [{
html: '1'
},{
html: '2'
}, {
html: '3'
}]
});
// Infinite carousel
var carousel = new SS.BufferedCarousel({
itemCount: 3,
createItem: function (index) {
return {html: (i+1)+ '' };
}
});
सिद्धांत रूप में, स्लाइडिंग क्षेत्र काफी सरल है। आरंभीकरण के दौरान और हर बार स्कोप बदलते समय, हम स्लाइडिंग क्षेत्र को अपडेट करते हैं।
bufferCards: function (index) {
// Quick return if there is nothing to do
if ( this .lastBufferedIndex == index) { return ; }
this .lastBufferedIndex = index;
// Initialize variables
var
// size of the window
bufferSize = this .bufferSize,
// constrained start index of the window
start = (index-bufferSize).constrain(0, this .itemCount-1),
// constrained end index of the window
end = (index+bufferSize).constrain(0, this .itemCount-1),
items = this .items,
// flag to determine if any items were added/removed
changed = false ,
// will be set to the item where its position == index
activeCard;
// make sure the index is within bounds
index = index.constrain(0, this .itemCount-1);
// cull existing items
var i = 0;
while (i < items.length) {
var item = items.get(i),
itemIndex = item.carouselPosition;
if (itemIndex end) {
this .remove(item, true );
changed = true ;
}
else {
i++;
}
}
// function to create a card and add to the carousel
var createCard = function (carouselPos, layoutPos) {
var card = this .createItem(i);
if (card) {
card.carouselPosition = carouselPos;
if (layoutPos != null ) {
this .insert(layoutPos, card);
}
else {
this .add(card);
}
if (carouselPos == index) {
activeCard = card;
}
changed = true ;
}
};
// add new items
if (items.length) { // if existing items, add to the left and right
var first = items.first().carouselPosition,
last = items.last().carouselPosition;
for ( var i = first-1; i>=start; i--) {
if (i >= 0) {
createCard.call( this , i, 0);
}
}
for ( var i = last+1; i<=end; i++) {
createCard.call( this , i);
}
}
else { // if no existing items, just add cards
for ( var i = start; i= 0) {
createCard.call( this , i);
}
}
}
// if changed, make sure the layout is updated
// also, update the active item if needed
if (changed) {
this .doLayout();
var activeItem = this .layout.getActiveItem();
if (activeCard && activeItem != activeCard) {
this .layout.setActiveItem(activeCard);
}
}
}
डेटा अधिग्रहण और कैशिंग
ShopStyle एक एपीआई प्रदान करता है जो आपको एक श्रेणी से उत्पादों को प्राप्त करने और फ़िल्टर करने की अनुमति देता है। पेजिंग के कार्यान्वयन के लिए आवश्यक डेटा के कुछ हिस्सों को प्राप्त करने की संभावना भी है। डेवलपर्स डेटा का सीधा उपयोग करना चाहते थे, साथ ही नेटवर्क से डेटा प्राप्त करने में होने वाली समस्याओं से बचने के लिए, जिसका मतलब था कैशिंग छवियों।
इन उद्देश्यों के लिए, डेटा पुनर्प्राप्ति और उत्पाद डेटा की कैशिंग को आसान बनाने के लिए DataCache वर्ग बनाया गया था। मूल रूप से, DataCache में एक साधारण फ़ंक्शन "getItems" होता है, जो उत्पादों की एक श्रृंखला को स्वीकार करता है और प्राप्त होने के बाद उत्पादों के बारे में डेटा को संसाधित करने के लिए कॉलबैक फ़ंक्शन भी करता है, यह समान अनुरोधों से बचने के लिए कुछ सरल प्रसंस्करण और सीधे प्राप्त किए गए डेटा को भी वापस करता है। नतीजतन, कैशिंग प्राथमिक हो जाता है - सभी आवश्यक है कि उत्पादों की एक श्रृंखला के साथ getItems को कॉल करें। इस प्रक्रिया को चित्र में दर्शाया गया है:
जब getItems को पहले 100 तत्वों के लिए बुलाया जाता है, तो ShopStyle के लिए अनुरोध भेजा जाता है। बाद के getItems में 1-10 और 11-20 तत्वों के लिए अनुरोध, एप्लिकेशन निर्धारित करता है कि यह डेटा पहले से ही अनुरोध किया गया है और एपीआई के लिए अतिरिक्त अनुरोध नहीं भेजता है। जब कोई प्रतिक्रिया आती है, तो संबंधित कॉलबैक फ़ंक्शन कहलाते हैं। प्राप्त करने के लिए अगला कॉल तत्वों के लिए। यह डेटा प्राप्त होने के बाद से ही तुरंत व्युत्क्रम फ़ंक्शन को कॉल करता है।
XTemplate
उत्पादों को प्रदर्शित करते समय, प्रत्येक पृष्ठ ग्रिड लेआउट में 8 या 9 (अभिविन्यास के आधार पर) तत्वों को प्रदर्शित करता है। ज्यादातर मामलों में, फ़्लोटिंग तत्वों का उपयोग किया जाता है, लेकिन डेवलपर्स थोड़ा अलग रास्ता लेना चाहते थे और CSS3 की विशेषताओं का उपयोग करते थे:
SS.PagedCarousel.Indicator = Ext.extend(Ext.Component, {
baseCls: "ss-pagedCarousel-indicator" ,
initComponent: function () {
if ( this .carousel.rendered) {
this .render( this .carousel.body);
}
else {
this .carousel.on( 'render' , function () {
this .render( this .carousel.body);
}, this , {single: true });
}
},
onRender: function () {
SS.PagedCarousel.Indicator.superclass.onRender.apply( this , arguments);
this .positionIndicator = this .el.createChild({tag: 'span' });
},
onBeforeCardSwitch: function (carousel, card) {
if (card) {
var position = card.carouselPosition/( this .carousel.itemCount-1),
position = isNaN(position) ? 0 : position*100,
el = this .el;
this .positionIndicator[ this .carousel.direction== 'vertical' ? 'setTop' : 'setLeft' ](position.toFixed(2)+ "%" );
el.setStyle( 'opacity' , '1' );
if ( this .hideTimeout != null ) {
clearTimeout( this .hideTimeout);
}
this .hideTimeout = setTimeout( function () {
el.setStyle( 'opacity' , '0' );
}, 1500);
}
},
});
मोबाइल इंटरनेट
एप्लिकेशन का टच संस्करण मूल एप्लिकेशन की पूरी प्रतिलिपि नहीं है - उदाहरण के लिए, खोज विकल्प लागू किया गया था, जबकि मूल एप्लिकेशन एक फिल्टर तंत्र का उपयोग करता है। यह सब मोबाइल प्लेटफ़ॉर्म पर उपलब्ध एप्लिकेशन के एनालॉग्स बनाते समय स्नेहा टच के फायदों को प्रदर्शित करता है, और चूंकि यह अभी भी एक इंटरनेट एप्लीकेशन है, यह वेबओएस और एंड्रॉइड (डेवलपर्स के लाइब्रेरी में संबंधित समर्थन समाप्त होने के बाद) दोनों पर काम करेगा।
खैर, मूल लेख के लेखक ने शुगर से ब्रायन शुगर और ट्रे मैटेसन को एपीआई तक पहुंच प्रदान करने के लिए धन्यवाद दिया, साथ ही प्रासंगिक मुद्दों पर सलाह देने और उन सभी को शुभकामनाएं दीं।