2009-08-02 14 views
5

मैं एक ऐसे प्रोजेक्ट पर काम कर रहा हूं जहां हम उपयोगकर्ता को अपना आधा पूरा फॉर्म सहेजने की क्षमता देना चाहते हैं ताकि वे बाद में वापस आ सकें और इसे पूरा कर सकें। मैं यह पता लगाने के साथ संघर्ष कर रहा हूं कि मैं यह कैसे करना चाहता हूं। क्या मैं उन्हें एक ही पूल में पूरा एप्लिकेशन के साथ ही एक विशेष स्थिति के साथ सहेजता हूं? मैं वास्तव में पूरा अनुप्रयोगों की अखंडता को त्यागना नहीं चाहता हूं जब तक कि मैं उन्हें नहीं बनना चाहता हूं।आधा पूरा फॉर्म कैसे बचाएं

क्या मुझे अपूर्ण अनुप्रयोगों को रखने के लिए एक अलग स्कीमा में एक ही डेटाबेस संरचना बनाना चाहिए? मैं अपूर्ण अनुप्रयोगों के लिए डेटाबेस की बाधाओं और शून्य क्षेत्रों पर यह अन्य स्कीमा अधिक ढीला हो सकता था।

क्या ऐसा करने का कोई आसान तरीका है? क्या कोई तरीका है कि मैं केवल व्यूस्टेट को सहेज सकता हूं और बाद में इसे पुनर्स्थापित कर सकता हूं?

किसी भी सलाह के लिए धन्यवाद!

उत्तर

1

अपने भरे गए आवेदन पत्र और इन "आधा" राज्यों के बीच मतभेद की एक जोड़ी हो सकता है:

  1. आप कहते हैं के रूप में, सबसे मान्यता अनुचित है, खेतों अशक्त हो जाएगा, पार सत्यापन probbably नहीं किया जा सकता।
  2. आपको डेटा में मनमाने ढंग से खोज क्षमताओं की आवश्यकता नहीं है।

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

ऐसा लगता है कि सी # तकनीक में जावा के साथ कुछ समानता है, कम से कम मैं इस article को सही ढंग से समझता हूं।

मुझे लगता है कि कुछ सरल "saveAsAString" और "readFromString" कोड हाथ-क्राफ्टिंग थोड़ा सुस्त होगा लेकिन अगर कोई मानक नहीं है तो बहुत ही व्यावहारिक है। नेट तकनीक मौजूद है।

+0

मुझे लगता है कि यह वह दृष्टिकोण है जिसे मैं लेना चाहता हूं, लेकिन धारावाहिक भाग वह हिस्सा है जिसकी मुझे सहायता चाहिए। –

+0

एक रिलीज आलेख प्रतीत होता है जो एक संदर्भ जोड़ा गया है, शायद यहां कोई भी शर्मिंदा नहीं होने पर धारावाहिक तकनीकों के बारे में एक दूसरा प्रश्न पूछें। – djna

0

मैं निश्चित रूप से इसे डेटाबेस में सहेज लेगा। एक विशेष स्थिति के साथ सहेजने की आपकी योजना (पूर्ण नाम का एक बुलियन ध्वज काम करेगा)। फिर आप एक ऐसा दृश्य बना सकते हैं जो केवल आइटम खींचता है जहां पूर्ण = सत्य, जिसे पूर्ण अनुप्रयोग कहा जाता है।

3

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

+0

क्या आप वेबफॉर्म को क्रमबद्ध करने पर कोई संकेत दे सकते हैं? यह विज़ार्ड नियंत्रण वाला एक पृष्ठ है जिसमें कई कदम हैं। –

+0

मैं एक धारावाहिक LOB होने के साथ सहमत हूं- इसका मतलब है कि आपके पास डीबी में बहुत से कमजोर कॉलम नहीं हैं। डीबी में सहेजना संभव है, लेकिन मैं इसकी अनुशंसा नहीं करता हूं। @ माइकसी- आप वेबफॉर्म को क्रमबद्ध नहीं करेंगे, लेकिन डोमेन मॉडल जो यह बाध्य है। – RichardOD

+0

@ रिचर्डोड - कोई उदाहरण? –

4

मैं एक ही समस्या से जूझ रहा था। एक अंतर यह है कि मेरी विधि में AJAX ऑटो-सेविंग शामिल है जो आप जीमेल और ब्लॉगर में देखते हैं। लेकिन वास्तव में, कार्यान्वयन में बदलाव नहीं करना चाहिए।

समस्या यह थी कि मैं सामान्य सारणी में सहेजना नहीं चाहता था क्योंकि उसे सत्यापन (पूर्णांक, मुद्राएं, तिथियां इत्यादि मान्य करना) आवश्यक था। और मैं उस बारे में उपयोगकर्ता को तब तक नहीं छीनना चाहता था जब वे वास्तव में छोड़ने की कोशिश कर रहे हों।

मैं आखिरकार आया था, जिसे अजाक्ससेवडेटा नामक एक टेबल था। यह डेटाबेस में एक स्थायी तालिका है, लेकिन इसमें मौजूद डेटा अस्थायी है। दूसरे शब्दों में, यह उपयोगकर्ता के डेटा को अस्थायी रूप से तब तक संग्रहीत करेगा जब तक वे वास्तव में पृष्ठ को पूरा न करें और अगले पर जाएं।

तालिका बस कुछ स्तंभों से बना है:

AjaxSavedDataID - int:

प्राथमिक कुंजी।

UserID - int:

उपयोगकर्ता (आसान पर्याप्त) की पहचान करें।

पृष्ठ का नाम दिखना - varchar (100):

आवश्यक आप एक से अधिक पृष्ठों के साथ काम कर रहे हैं।

ControlID - varchar (100):

मैं इस एक ControlID फोन है, लेकिन इसे वास्तव में सिर्फ ClientID संपत्ति जो .NET WebControls के सभी के लिए उजागर करता है। इसलिए यदि उदाहरण के लिए txtEmail उपयोगकर्ता नाम के संपर्क में था, तो क्लाइंट आईडी संपर्क_txtEmail होगा।

मूल्य - varchar (max):

मूल्य उपयोगकर्ता किसी दिए गए क्षेत्र या नियंत्रण के लिए प्रवेश किया।

DateChanged - दिनांक:

दिनांक मान जोड़ा गया है या संशोधित।

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

यह ऑटो-सेविंग कार्यक्षमता techinsurance.com पर एक बहुत ही गतिशील ऑनलाइन व्यापार बीमा आवेदन में अपना रास्ता बनायेगी ताकि इसे थोड़ा अधिक उपयोगकर्ता के अनुकूल बनाया जा सके।

function getNewHTTPObject() { 
    var xmlhttp; 

    /** Special IE only code */ 
    /*@cc_on 
    @if (@_jscript_version >= 5) 
    try { 
     xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); 
    } 
    catch (e) { 
     try { 
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
     } 
     catch (E) { 
      xmlhttp = false; 
     } 
    } 
    @else 
     xmlhttp = false; 
    @end 
    @*/ 

    /** Every other browser on the planet */ 
    if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { 
     try { 
      xmlhttp = new XMLHttpRequest(); 
     } 
     catch (e) { 
      xmlhttp = false; 
     } 
    } 

    return xmlhttp; 
} 

function AjaxSend(url, myfunction) { 
    var xmlHttp = getNewHTTPObject(); 
    url = url + "&_did=" + Date(); 
    xmlHttp.open("GET", url, true); 
    var requestTimer = setTimeout(function() { xmlHttp.abort(); }, 2000); 
    xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 
    xmlHttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2005 00:00:00 GMT"); 
    xmlHttp.onreadystatechange = function() { 
     if (xmlHttp.readyState != 4) 
      return; 
     var result = xmlHttp.responseText; 
     myfunction(result); 
    }; 
    xmlHttp.send(null); 
} 

// Autosave functions 
var SaveQueue = []; // contains id's to the DOM object where the value can be found 
var SaveQueueID = []; // contains id's for binding references (not always the same) 

function ArrayContains(arr, value) { 
    for (i = 0; i < arr.length; i++) { 
     if (arr[i] == value) 
      return true; 
    } 

    return false; 
} 

function GetShortTime() { 
    var a_p = ""; 
    var d = new Date(); 
    var curr_hour = d.getHours(); 

    if (curr_hour < 12) 
     a_p = "AM"; 
    else 
     a_p = "PM"; 

    if (curr_hour == 0) 
     curr_hour = 12; 
    else if (curr_hour > 12) 
     curr_hour = curr_hour - 12; 

    var curr_min = d.getMinutes(); 
    curr_min = curr_min + ""; 

    if (curr_min.length == 1) 
     curr_min = "0" + curr_min; 

    return curr_hour + ":" + curr_min + " " + a_p; 
} 

function Saved(result) { 
    if (result == "OK") { 
     document.getElementById("divAutoSaved").innerHTML = "Application auto-saved at " + GetShortTime(); 
     document.getElementById("divAutoSaved").style.display = ""; 
    } 
    else { 
     document.getElementById("divAutoSaved").innerHTML = result; 
     document.getElementById("divAutoSaved").style.display = ""; 
    } 
} 

function getQueryString(name, defaultValue) { 
    var query = window.location.search.substring(1); 
    var vars = query.split("&"); 
    for (var i = 0; i < vars.length; i++) { 
     var pair = vars[i].split("="); 
     if (pair[0] == name) { 
      return pair[1]; 
     } 
    } 

    return defaultValue; 
} 

function urlencode(str) { 
    return escape(str).replace(/\+/g, '%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40'); 
} 

function AutoSave() { 
    if (SaveQueue.length > 0) { 
     var url = "/AjaxAutoSave.aspx?step=" + getQueryString("step", "ContactInformation"); 

     for (i = 0; i < SaveQueue.length; i++) { 
      switch (document.getElementById(SaveQueue[i]).type) { 
       case "radio": 
        if (document.getElementById(SaveQueue[i]).checked) 
         url += "&" + SaveQueueID[i] + "=" + urlencode(document.getElementById(SaveQueue[i]).value); 
        break; 
       case "checkbox": 
        if (document.getElementById(SaveQueue[i]).checked) 
         url += "&" + SaveQueueID[i] + "=" + urlencode(document.getElementById(SaveQueue[i]).value); 
       default: 
        url += "&" + SaveQueueID[i] + "=" + urlencode(document.getElementById(SaveQueue[i]).value); 
      } 
     } 

     SaveQueue = []; 
     SaveQueueID = []; 
     AjaxSend(url, Saved); 
    } 
} 

function AddToQueue(elem, id) { 
    if (id == null || id.length == 0) 
     id = elem.id; 

    if (!ArrayContains(SaveQueueID, id)) { 
     SaveQueue[SaveQueue.length] = elem.id; 
     SaveQueueID[SaveQueueID.length] = id; 
    } 
} 

अपने पृष्ठ में जोड़ें इस काम करने के लिए:

window.setInterval("AutoSave()", 5000); 

और एक को यह लागू करने के लिए

मामले आप रुचि रखते हैं, यहाँ जावास्क्रिप्ट कि अनुमति देता है ऑटो की बचत है टेक्स्टबॉक्स, ड्रॉपडाउनलिस्ट, लिस्टबॉक्स, या चेकबॉक्स आपको बस इस विशेषता को जोड़ने की आवश्यकता है:

onchange="AddToQueue(this)" 

... या इसके लिए एक रेडियोबटन सूची या चेकबॉक्स सूची:

onchange="AddToQueue(this, '" + this.ClientID + "')" 
+0

तो जब आप नियंत्रणों को सहेज रहे हैं तो क्या आप नियंत्रण संग्रह के माध्यम से बस फिर से काम करते हैं? –

+0

दरअसल, चूंकि यह AJAX- आधारित समाधान है, इसलिए बचत जावास्क्रिप्ट के माध्यम से प्रति-परिवर्तन आधार पर की जाती है। मेरे पास उन सभी फ़ील्ड पर जावास्क्रिप्ट ऑनचेंज ईवेंट हैं जो उपयोगकर्ता द्वारा किए गए किसी भी बदलाव का पता लगाते हैं और उन परिवर्तनों को सरणी में जोड़ते हैं। और फिर मेरे पास एक सेट इंटरवल कॉल है जो सरणी को खाली करता है और उन सभी परिवर्तनों को AJAX के माध्यम से प्रत्येक 5 सेकंड में एक अलग एएसपीएक्स पृष्ठ पर भेजता है। इस तरह यह बैंडविड्थ का अच्छा उपयोग करने के लिए केवल बदलेगा और कुछ भी नहीं बदलेगा। –

+0

वैसे, यह सभी AJAX सामान पूरी तरह से कस्टम है। मैंने .NET की AJAX सामग्री का उपयोग करने की कोशिश करने से भी परेशान नहीं किया क्योंकि यह सिर्फ मुझे भ्रमित कर रहा था। –

-1

कभी सिल्वरलाइट का उपयोग करने के बारे में सोचा? सिल्वरलाइट में पृथक भंडारण है, मैंने वहां कई उदाहरण देखे हैं जहां डेवलपर्स महंगा क्लाइंट-साइड डेटा स्टोर करने के लिए पृथक भंडारण का उपयोग करते हैं।

http://pietschsoft.com/post/2008/10/Silverlight-Client-Side-Database-via-LINQ-and-Isolated-Storage.aspx

और फिर js का उपयोग कर एक बाहर में डेटा प्राप्त करने के:

http://msdn.microsoft.com/en-us/library/cc221414%28VS.95%29.aspx

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

अधिक gr एक नया डेटाबेस जोड़ना भयानक?

एक नीचे की ओर एक मशीन निर्भर समाधान है।

आंशिक रूपों की बचत के सही लक्ष्य पर निर्भर करता है? क्या ऐसा है कि इसे अन्य मशीनों पर लाया जा सके? यदि ऐसा है तो यह सही समाधान नहीं है और डीबी बचत एक बेहतर बुराई है।

+0

सिल्वरलाइट लागू नहीं है। –

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