8

मैं एक रेल ऐप का निर्माण कर रहा हूं जो क्लाउड को सीधे अपडेट करने के लिए वेब सॉकेट का उपयोग करने के लिए पुशर का उपयोग करता है। जावास्क्रिप्ट में:जावास्क्रिप्ट और ईआरबी टेम्पलेट्स (रेल) दोनों का उपयोग करते समय DRY कैसे रहें

channel.bind('tweet-create', function(tweet){ //when a tweet is created, execute the following code: 
    $('#timeline').append("<div class='tweet'><div class='tweeter'>"+tweet.username+"</div>"+tweet.status+"</div>"); 
}); 

यह कोड और प्रस्तुति का गंदा मिश्रण है। तो प्राकृतिक समाधान एक जावास्क्रिप्ट टेम्पलेट का उपयोग करना होगा। शायद पर्यावरण या मूंछें:

//store this somewhere convenient, perhaps in the view folder: 
tweet_view = "<div class='tweet'><div class='tweeter'>{{tweet.username}}</div>{{tweet.status}}</div>" 

channel.bind('tweet-create', function(tweet){ //when a tweet is created, execute the following code: 
    $('#timeline').append(Mustache.to_html(tweet_view, tweet)); //much cleaner 
}); 

यह अच्छा है और सब है, सिवाय इसके, मैं अपने आप को दोहरा रहा हूँ। मूंछ टेम्पलेट ईआरबी टेम्पलेट्स के समान 99% है जो मैंने पहले ही सर्वर से एचटीएमएल प्रस्तुत करने के लिए लिखा है। मूंछ और ईआरबी टेम्पलेट का इच्छित आउटपुट/उद्देश्य 100% समान है: एक ट्वीट ऑब्जेक्ट को ट्वीट एचटीएमएल में बदलने के लिए।

इस पुनरावृत्ति को खत्म करने का सबसे अच्छा तरीका क्या है?

अद्यतन: भले ही मैंने अपने स्वयं के प्रश्न का उत्तर दिया, मैं वास्तव में अन्य लोगों से अन्य विचार/समाधान देखना चाहता हूं - इसलिए बक्षीस!

+1

: मूंछ (जिसे आपने पहले ही उल्लेख किया है) सर्वर-साइड प्रतिपादन के लिए भी अनुमति देता है (देखें: कार्यान्वयन के लिए http://mustache.github.com/)। प्रवाह अब बन जाता है: एक मूंछ-टेम्पलेट + एन लगातार क्लाइंट-साइड रेंडरिंग का उपयोग करके 1 इंटिटल सर्वर-साइड रेंडरिंग एक ही मूंछ-टेम्पलेट –

+0

का उपयोग करके बहुत धन्यवाद। मैं उन पर एक नज़र डालेगा। – user94154

+0

fyi: मैंने अभी एक समान प्रश्न पूछा है (मूंछ बीसी के विकल्पों की तलाश में)। हालांकि प्रवाह वही रहेगा। शायद यह भी मदद करता है। देखें: http://stackoverflow.com/questions/6831718/client-side-templating-language-with-java-compiler-as-well-dry-templating –

उत्तर

5

आईएमओ ऐसा करने का सबसे आसान तरीका है जब एक नया ट्वीट बनाया गया है तो पृष्ठ को अपडेट करने के लिए AJAX का उपयोग करना शामिल होगा। इसके लिए दो फाइलें बनाने की आवश्यकता होगी, पहला मानक HTML.erb फ़ाइल है और दूसरा js.erb फ़ाइल है। Html.erb मानक रूप होगा जो डेटाबेस से खींचने के बाद सभी ट्वीट्स को फिर से प्रदर्शित और प्रदर्शित कर सकता है।

$('#timeline').append("<div class='tweet'><div class='tweeter'><%= tweet.username %></div><%= tweet.status %></div>") 

नए ट्वीट के लिए अपने फॉर्म में आप को जोड़ने के लिए की आवश्यकता होगी:

:remote => true 

जो सक्षम हो जाएगा js.erb फ़ाइल खोलने के बाद नए ट्वीट जोड़ने के लिए अपने सरल जावास्क्रिप्ट, यानी हो जाएगा AJAX। फिर बनाने कार्रवाई में आप इस तरह कोड जोड़ने की जरूरत: यदि आप एक AJAX फ़ॉर्म सक्षम के साथ एक ट्वीट पोस्ट करते हैं,

def create 
...Processing logic... 
    respond_to do |format| 
    format.html { redirect_to tweets_path } 
    format.js 
    end 
end 

इस उदाहरण में, इसे चलाने जो कुछ कोड create.js में है द्वारा कॉल का जवाब होगा .erb (जो $ ('# टाइमलाइन') होगा। ऊपर से कोड संलग्न करें)। अन्यथा यह जहां भी आप इसे भेजना चाहते हैं उसे रीडायरेक्ट करेगा (इस मामले में ट्वीट्स के लिए 'इंडेक्स')। यह आप जो करने की कोशिश कर रहे हैं उसे पूरा करने के लिए सबसे कठिन और स्पष्ट तरीका है।

+0

प्रतिक्रिया के लिए धन्यवाद, लेकिन यह पुनरावृत्ति की समस्या को कैसे हल करता है ? Js.erb फ़ाइल में divs को html.erb आंशिक रूप से सटीक तरीके से लिखा जाएगा। – user94154

+2

अच्छी तरह से आप क्या कर सकते हैं दो (साझा/_tweet_item.html.erb) के बीच एक तीसरा साझा आंशिक है। तो उदाहरण के लिए अपनी एचटीएमएल फाइल में आप केवल '<% = रेंडर: आंशिक =>' साझा/tweet_item 'प्रस्तुत कर सकते हैं, संग्रह => @tweets_array%>' जो आपके सरणी में सभी ट्वीट्स के साथ आंशिक पर फिर से चालू होगा । इसी तरह आपकी create.js.erb फ़ाइल में आप '$ ("टाइमलाइन") जैसे कुछ कर सकते हैं। ("<% = escape_javascript (प्रस्तुत करें (' साझा/tweet_item ', @tweet))%>")' जो संलग्न करेगा एक नया आंशिक दिया गया है कि आपने इसे @tweet इंस्टेंस वैरिएबल –

+0

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

3

अब तक, मुझे मिला सबसे अच्छा समाधान Isotope था।

यह आपको जावास्क्रिप्ट का उपयोग करके टेम्पलेट्स लिखने देता है जिसे क्लाइंट और सर्वर दोनों द्वारा प्रस्तुत किया जा सकता है।

2

मैं इस की कोशिश की है नहीं है, लेकिन यह सिर्फ एक संभव समाधान के रूप में मेरे लिए हुई:

आपके विचार में एक छिपा div जो एक उदाहरण टेम्पलेट (मैं Haml यहाँ संक्षिप्तता के लिए उपयोग कर रहा हूँ) शामिल हैं बनाने के लिए:

#tweet-prototype{:style => "display:none"} 
    = render :partial => Tweet.prototype 

आपका ट्वीट आंशिक अब ट्वीट के रूप में एक ट्वीट प्रस्तुत कर सकता है।

.tweet 
    .tweeter 
     = tweet.username 
    .status 
     = tweet.status 

जब ट्वीट प्रोटोटाइप आप क्षेत्रों आप js-टेम्पलेट प्रतिस्थापन वाक्य रचना करना चाहते हैं निर्धारित बनाते समय, आप निश्चित रूप से इस सूख सकता है, लेकिन मैं इसे यहाँ उदाहरण प्रयोजनों के लिए पूरी तरह से शामिल कर रहा हूँ।

# tweet.rb 
def self.prototype 
    Tweet.new{:username => "${tweet.username}", :status => "${tweet.status}"} 
end 

ग्राहक आप की तरह कुछ करना चाहते हैं पर: अंतिम भाग कैसे आप अपने templating कर रहे हैं पर निर्भर हो जाएगा

var template = new Template($('#tweet-prototype').html()); 
template.evaluate(.. your tweet json..); 

, लेकिन यह ऐसा ही कुछ होगा।

जैसा कि पहले बताया गया था, मैंने इस तकनीक की कोशिश नहीं की है, और यह आपको टेम्पलेट में सीधे लूप या सशर्त स्वरूपण जैसी चीजें करने नहीं देगा, लेकिन आप निश्चित रूप से कुछ रचनात्मकता के साथ इसे प्राप्त कर सकते हैं।

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

मुझे आशा है कि इससे मदद मिलती है!

3

मैं जावास्क्रिप्ट के साथ सभी ट्वीट्स प्रस्तुत करता हूं। सर्वर पर HTML को प्रस्तुत करने के बजाय, प्रारंभिक डेटा को अपने पृष्ठ के शीर्ष में जेएस के रूप में सेट करें। जब पृष्ठ लोड होता है, तो जेएस के साथ ट्वीट प्रस्तुत करें।

अपने सिर में:

%head 
    :javascript 
    window.existingTweets = [{'status' : 'my tweet', 'username' : 'glasner'}]; 

एक जे एस फ़ाइल में:

$.fn.timeline = function() { 
    this.extend({ 
    template: "<div class='tweet'><div class='tweeter'>{{tweet.username}}</div>{{tweet.status}}</div>", 
    push: function(hash){ 
     // have to refer to timeline with global variable 
     var tweet = Mustache.to_html(timeline.template, hash)  
     timeline.append(tweet); 
    } 
    }); 

    window.timeline = this; 

    channel.bind('tweet-create', this.push); 

    // I use Underscore, but you can loop through however you want 
    _.each(existingTweets,function(hash) { 
    timeline.push(hash); 
    }); 

    return this 
}; 


$(document).ready(function() { 
    $('#timeline').timeline(); 
}); 
+0

यह एक और अच्छा जवाब है, लेकिन मुद्दा यह है कि अब आप खोज इंजन अनुकूल नहीं हैं। – jonnii

+0

अच्छा बिंदु। यह तकनीक केवल ऐप्स के लिए है, जहां आप दीर्घकालिक सामग्री नहीं बना रहे हैं। – Jordan

1

और जावास्क्रिप्ट के बीच टेम्पलेट साझा करने के लिए सक्षम होने के लिए एक मूंछें टेम्पलेट वहाँ smt_rails है साथ रेल: https://github.com/railsware/smt_rails (" रेल 3 के लिए साझा मूंछ टेम्पलेट्स 3) और पोयरोट: https://github.com/olivernn/poirot। भविष्य में संदर्भ के लिए

+0

इससे मुझे एक गुच्छा मदद मिली, धन्यवाद! – WattsInABox

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