2010-08-13 13 views
16

में मानों को इंजेक्ट करें मैं एक यूआरएल के खंड (जेएसएफ) में खंड (#) से मूल्य इंजेक्ट करने का एक तरीका ढूंढ रहा हूं, वैसे ही क्वेरी-पैरामीटर मूल्य इंजेक्शन दिए जाते हैं। मैं यूआरएल टुकड़े बनाने के लिए बेन आलमैन की बुकमार्क करने योग्य jQuery प्लगइन (http://benalman.com/projects/jquery-bbq-plugin/) का उपयोग कर रहा हूं। मैं उम्मीद कर रहा था कि सुंदरफेस से कस्टम रेगेक्स पैटर्न मेरी समस्या का समाधान करने का एक तरीका हो सकता है लेकिन अब तक मैं असफल रहा हूं।एक यूआरएल से टुकड़ा (हैश) प्राप्त करें और बीन

(http://ocpsoft.com/docs/prettyfaces/snapshot/en-US/html_single/#config.pathparams.regext)

मैं यहाँ मेरी स्थिति को परिभाषित करने और अगर किसी भी एक एक विचार है, मैं उन्हें बाहर की कोशिश करना अच्छा लगेगा चाहते हैं। 3.3.3,
स्प्रिंग: 3.0.2.RELEASE,
हाइबरनेट: 3.5.3-फाइनल,
JSF: 2.0.2-FCS,
PrettyFaces

मैं
RichFaces उपयोग कर रहा हूँ: 3.0.1

वेब एप्लिकेशन जेनरेट करता है, यूआरएल के प्रकार जहां पैरामीटर हैश (#) के बाद सूचीबद्ध हैं। विचार है कि AJAX आधारित बुकमार्क करने योग्य URL होना चाहिए। इसलिए हर बार जब मैं उस तत्व पर क्लिक करता हूं जो सिस्टम की स्थिति को बदलता है, तो हैश को एजेक्स के माध्यम से सर्वर पर भेजा जाता है और हैश को फिर से लिखने के बाद यूआरएल भेजा जाता है। हैश के बाद 1 से 3 पैरामीटर हो सकते हैं, पैरामीटर की संख्या वैकल्पिक हैं।

मेरा लक्ष्य है, जब उपयोगकर्ता (हैश के साथ) यूआरएल बुकमार्क और से बचाया पृष्ठ पर दोबारा पेज सही मान प्रणाली में इंजेक्षन और ( query- पहले वाली स्थिति में पेज कल्पना की तरह करना चाहिए पैरामीटर)।

नीचे, मेरे पास नियमित अभिव्यक्ति है जो हैश के बाद सभी पैरामीटर को पकड़ लेगा।

//URL: 
http://localhost:8080/nymphaea/workspace/#node=b48dd073-145c-4eb6-9ae0-e1d8ba90303c&lod=75e63fcd-f94a-49f5-b0a7-69f34d4e63d7&ln=en 

//Regular Expression:  
\#(\w*\=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}))|\&(\w*\=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}))|\&(\w*\=\w{2}) 

मैं जानता हूँ कि वहाँ वेबसाइटें हैं कि कुछ कैसे वहाँ सर्वर साइड तर्क में URL खंड भेजने के लिए,

से मूल्यों सुई वहाँ वैसे भी है सर्वर पक्ष सेम में यूआरएल टुकड़े?

उत्तर

8

आप जो एक गुप्त फ़ॉर्म जो अपने आप एसिंक्रोनस रूप से प्रस्तुत जब इनपुट क्षेत्र बदल गया है की एक इनपुट फ़ील्ड भरता window.onhashchange की मदद से यह कर सकते हैं।

यहाँ Facelets पेज के एक किकऑफ़ उदाहरण है:

package com.stackoverflow.q3475076; 

import javax.faces.bean.ManagedBean; 
import javax.faces.bean.RequestScoped; 
import javax.faces.event.AjaxBehaviorEvent; 

@ManagedBean 
@RequestScoped 
public class Bean { 

    private String fragment; 

    public void processFragment(AjaxBehaviorEvent event) { 
     // Do your thing here. This example is just printing to stdout. 
     System.out.println("Process fragment: " + fragment); 
    } 

    public String getFragment() { 
     return fragment; 
    } 

    public void setFragment(String fragment) { 
     this.fragment = fragment; 
    } 

} 

सब है कि:

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html"> 
    <h:head> 
     <title>SO question 3475076</title> 
     <script> 
      window.onload = window.onhashchange = function() { 
       var fragment = document.getElementById("processFragment:fragment"); 
       fragment.value = window.location.hash; 
       fragment.onchange(); 
      } 
     </script> 
     <style>.hide { display: none; }</style> 
    </h:head> 
    <h:body> 
     <h:form id="processFragment" class="hide"> 
      <h:inputText id="fragment" value="#{bean.fragment}"> 
       <f:ajax event="change" execute="@form" listener="#{bean.processFragment}" render=":showFragment" /> 
      </h:inputText> 
     </h:form> 
     <p>Change the fragment in the URL. Either manually or by those links: 
      <a href="#foo">foo</a>, <a href="#bar">bar</a>, <a href="#baz">baz</a> 
     </p> 
     <p>Fragment is currently: <h:outputText id="showFragment" value="#{bean.fragment}" /></p> 
    </h:body> 
</html> 

यहाँ उचित सेम की तरह लग रहे तरीका बताया गया है।

ध्यान दें कि onhashchange ईवेंट अपेक्षाकृत नया है और पुराने ब्राउज़र द्वारा समर्थित नहीं है। ब्राउज़र समर्थन (अनिर्धारित और इतने पर) की अनुपस्थिति में, आप इसके बजाय setInterval() का उपयोग करके अंतराल पर window.location.hash जांचना चाहेंगे। उपर्युक्त कोड उदाहरण कम से कम एक अच्छा किकऑफ देना चाहिए। यह कम से कम एफएफ 3.6 और आईई 8 पर काम करता है।

+1

वाह, यह बस कमाल है, साझा करने के लिए धन्यवाद। अब मुझे जेएसएफ 2 पर एक नज़र डालना होगा। – clacke

+1

आईई 6/7 ब्राउज़र के लिए, jQuery हैशचेंज प्लगइन पर विचार करें। यह भी देखें http://stackoverflow.com/questions/5911899/ie6-7-back-forward-button-dont-change-window-location-hash – BalusC

3

यहां एक वाक्य रचनात्मक रूप से मान्य यूआरएल/यूआरआई से एक टुकड़ा निकालने का सबसे विश्वसनीय तरीका है।

URI uri = new URI(someString); 
String fragment = uri.getFragment(); 

आप कैसे एक सेम में इस इंजेक्षन क्या सर्वर साइड ढांचे का उपयोग कर रहे पर निर्भर करेगा, और क्या आप XML या एनोटेशन का उपयोग इंजेक्शन कर रहे हैं, या यह programmaticaly कर।

+0

आपके विचार के लिए धन्यवाद। मैं पेज रीलोड (GET) होने पर URL को पकड़ने का तरीका ढूंढ रहा हूं और getFragment() प्राप्त करने के बजाय, मान प्राप्त करने और संबंधित चर सेट करने के लिए इसे सही तरीके से पार्स करें। – tchoesang

+0

यह ठीक है कि विधि मौजूद है, लेकिन ब्राउज़र सर्वर पर खंड जानकारी नहीं भेजते हैं। यह HTTP यातायात लॉगिंग करके देखा जा सकता है। – pcjuzer

+1

तकनीकी रूप से सही होने पर, यह उत्तर व्यावहारिक रूप से और मौलिक रूप से गलत है। वेबब्रोसर द्वारा निर्धारित टुकड़ा [** नहीं होगा **] (http://en.wikipedia.org/wiki/Fragment_identifier#Processing) वेबसर्वर पर पहुंचें। – BalusC

1

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

यदि आप पूरी तरह से पृष्ठ को प्रतिपादित करते समय सर्वर-पक्ष को खंड पैरामीटर तक पहुंच प्राप्त करना चाहते हैं, तो आपको इसके बजाय पैरामीटर पैरामीटर के रूप में पैरामीटर के साथ पृष्ठ को फिर से लोड करना होगा।

संपादित करें:

if (window.location.hash != '') { 
    var newsearch = window.location.search; 
    if(newsearch != '') { 
    newsearch += '&'; 
    } 
    newsearch += window.location.hash.match(/#?(.*)/)[1]; 
    window.location.hash = ''; 
    window.location.search = newsearch; 
} 
+0

मैंने उस तकनीक को फेसबुक द्वारा उपयोग किया जहां पृष्ठ को पुनः लोड होने पर खंड पैरामीटर क्वेरी पैरामीटर में परिवर्तित कर दिए जाते हैं। मैं इस विचार को आजमा देना चाहता हूं। पेज यूआरएल पर क्वेरी पैराम्स के साथ खंड में यूआरएल में कैसे परिवर्तित किया जा सकता है? i.e. http://url.com/#a=1&b=2 -> http://url.com/?a=1&b=2 – tchoesang

+0

जोड़ा गया उदाहरण कोड। हालांकि, मैं सुझाव दूंगा कि आप पैराम्स को पार्स करने के लिए कोड लिखेंगे और उचित AJAX अनुरोध को बुकमार्क किए गए राज्य का पुनर्निर्माण करने के लिए तैयार करेंगे। साथ ही, मेरी कोड उदाहरण आपकी आवश्यकताओं के लिए बहुत आसान है, यह उदाहरण के लिए जांच नहीं करता है डुप्लिकेटेड पैरा और इसलिए समस्याएं तब चलती हैं जब उपयोगकर्ता चारों ओर क्लिक करना शुरू कर देता है और आप फिर से टुकड़े में चीजों को जोड़ना शुरू करते हैं। – clacke

+0

कोड उदाहरण बेकार है। बस 'window.location.hash' आपको पहले से ही खंड और' window.location.search' क्वेरी स्ट्रिंग देता है। ['Window.location'] (https://developer.mozilla.org/en/window.location) दस्तावेज़ पढ़ें। – BalusC

1

घड़ी इस सवाल का और विशेष रूप से उत्तर: JSP Servlet anchor

  • टुकड़ा सर्वर साइड पर नहीं देखा जा सकता पृष्ठ पुनः लोड करने के लिए आप इस कोड का उपयोग कर सकता है।
  • आप क्लाइंट-साइड पर खंड को निकाल सकते हैं, इसे परिवर्तित कर सकते हैं और सर्वर को अजाक्स के माध्यम से भेज सकते हैं।
+0

ग्रेट संदर्भ। विशेष रूप से [AJAXpatterns] (http://ajaxpatterns.org/Unique_URLs) लिंक। – clacke

0

आपके विचारों के लिए बहुत बहुत धन्यवाद & विशेष रूप से बलुससी (आपके लिए बहुत अधिक कुडोस)। मेरा अंतिम समाधान मामूली उत्परिवर्तन था और मैं आप सभी के साथ साझा करना चाहता हूं।

जब से मैं richfaces 3.3.3 का उपयोग कर रहा है, यह jsf1.2 का उपयोग कर, इसलिए कोई <f:ajax>

एक पारंपरिक स्थिति में की तरह है, आप एक आंतरिक लिंक <a id='internalLink'href='#internalLink'> को एक href की ओर इशारा करते के साथ एक लिंक पर क्लिक करने की संभावना है । मैं कई प्रीपेक्टेड घटकों का उपयोग कर रहा हूं जहां प्रत्येक क्लिक करने योग्य आइटम एक लिंक <a> नहीं है। यह कोई एचटीएमएल तत्व हो सकता है। बेन आलमैन के बुकमार्क करने योग्य jQuery प्लगइन का उपयोग करना बहुत उपयोगी था (http://benalman.com/projects/jquery-bbq-plugin/)

कृपया नीचे ध्यान दें कि, मैं प्रोग्रामिंग रूप से खंड/मूल्य के रूप में खंड के मान को सेट कर सकता हूं और निम्न कोड में मैं पुराने मान को एक नए के साथ बदल सकता हूं मूल्य jQuery.bbq.pushState(state,2) (या मैं बस पुराने मान jQuery.bbq.pushState(state) के पीछे जोड़ा हो सकता था)।

मेरे मामले में, ws->md->nd एक पदानुक्रमित डेटा है जहां उनमें से एक है और उसके माता-पिता की गणना सर्वर पर की जाती है, इसलिए मैं मूल मूल्य को बाल मूल्य के साथ प्रतिस्थापित करता हूं।

<ui:repeat value="#{workspaceController.modulesForWorkspace}" var="item"> 
<a4j:commandLink onclick="var state = {}; state['md'] = '#{item.uuid}'; 
    jQuery.bbq.pushState(state, 2);"  
    action="#{workspaceController.setSelectedModule}" 
    reRender="localesList" 
    oncomplete="selectNavigationElement(this.parentNode> 
    <f:param name="selectedModule" value="#{item.uuid}"/> 
    </a4j:commandLink> 
</ui:repeat> 

समृद्ध स्थानों में, यह पैरामीटर के साथ ब्राउज़र से सेटटर विधियों को कॉल करने का एक शानदार तरीका है। ध्यान दें कि sendURLFragment को 5 पैरामीटर के साथ जेएस विधि के रूप में माना जाता है और मान सर्वर पर पास किए जाते हैं (जो बहुत अच्छा है)।

<h:form id="processFragment" prependId="false" style="display: none"> 
    <h:inputText id="fragment" value="#{workspaceController.selectedWorkspace}">         
    <a4j:support event="onchange"/> 
    </h:inputText>  
<a4j:jsFunction name="sendURLFragment" reRender="workspaces"> 
<a4j:actionparam name="ws" assignTo="#{workspaceController.selectedWorkspace}"/> 
<a4j:actionparam name="md" assignTo="#{workspaceController.selectedModule}"/> 
<a4j:actionparam name="nd" assignTo="#{workspaceController.selectedContentNode}"/> 
<a4j:actionparam name="ld" assignTo="#{workspaceController.selectedLOD}"/> 
<a4j:actionparam name="ln" assignTo="#{workspaceController.contentNodeTreeLocale}" 
converter="localeConverter"/>        
</a4j:jsFunction> 
</h:form> 

जब आप नए यूआरएल को कॉपी-पेस्ट करते हैं और पेज लोड करते हैं तो यह काम करें।

window.onload = function(){ 
if(window.location.hash != ""){ 
    //Parse the fragment (hash) from a URL, deserializing it into an object    
    var deparamObj = jQuery.deparam.fragment(); 
    var ws= '', md= '', nd= '', ld= '', ln = '';    
    jQuery.each(deparamObj, function(key, value) {    
     switch(key){ 
      case 'ws': 
       ws = value; 
       break; 
      case 'md': 
       md = value; 
       break; 
      case 'nd': 
       nd = value; 
       break; 
      case 'ld': 
       ld = value; 
       break; 
      case 'ln': 
       ln = value; 
       break; 
      default: 
       break;   
     } 

    }); 
    sendURLFragment(ws,md,nd,ld,ln); 
} }; 
संबंधित मुद्दे