आंशिक रूप से हैंडलबार के माध्यम से चर पास करना


131

मैं वर्तमान में एक express.js आवेदन में handlebars.js के साथ काम कर रहा हूँ। चीजों को मॉड्यूलर रखने के लिए, मैंने अपने सभी टेम्प्लेट को विभाजन में विभाजित किया है।

मेरी समस्या : मुझे एक आंशिक आह्वान के माध्यम से चर पास करने का कोई तरीका नहीं मिला। मान लीजिए कि मेरे पास एक आंशिक है जो इस तरह दिखता है:

<div id=myPartial>
    <h1>Headline<h1>
    <p>Lorem ipsum</p>
</div>

मान लें कि मैंने इस आंशिक को 'myPartial' नाम से पंजीकृत किया है। एक अन्य टेम्पलेट में मैं फिर कुछ कह सकता हूं:

<section>
    {{> myPartial}}
</section>

यह ठीक काम करता है, आंशिक रूप से उम्मीद के मुताबिक प्रदान किया जाएगा और मैं एक खुश डेवलपर हूं। लेकिन अब मुझे जो चाहिए, वह है विभिन्न तरीकों से गुजरने का एक तरीका इस आह्वान के माध्यम से, उदाहरण के लिए एक आंशिक के भीतर जांच करने के लिए कि क्या एक शीर्षक दिया गया है या नहीं। कुछ इस तरह:

<div id=myPartial>
    {{#if headline}}
    <h1>{{headline}}</h1>
    {{/if}}
    <p>Lorem Ipsum</p>
</div>

और इनवोकेशन कुछ इस तरह दिखना चाहिए:

<section>
    {{> myPartial|'headline':'Headline'}}
</section>

या ऐसा।

मुझे पता है, कि मैं सभी डेटा को परिभाषित करने में सक्षम हूं, इससे पहले कि मैं एक टेम्पलेट प्रस्तुत करूं। लेकिन मुझे इसे करने के लिए एक तरीका चाहिए जैसे कि अभी समझाया गया है। क्या कोई संभावित तरीका है?

जवाबों:


214

हैंडलबार्स धारावाहिक एक दूसरा पैरामीटर लेते हैं जो आंशिक के लिए संदर्भ बन जाता है:

{{> person this}}

संस्करणों में v2.0.0 अल्फा और बाद में, आप नामित मापदंडों का हैश भी पास कर सकते हैं:

{{> person headline='Headline'}}

आप इन परिदृश्यों के लिए परीक्षण देख सकते हैं: https://github.com/wycats/handlebars.js/blob/ce74c36118ffed1779889d97e6a2a1028ae61510/spec/qunit_spec.js#L456-L462 https://github.com/whandats.com/ ब्लॉब / e290ec24f131f89ddf2c6aeb707a4884d41c3c6d / कल्पना / partials.js # L26-L32


5
यह तुरंत स्पष्ट नहीं है कि यह आपके परिदृश्य पर कैसे लागू होगा? क्या आप समाधान लिख सकते हैं - कृपया इसे अपने मामले में लागू करें? धन्यवाद!
सर्वरमैन

12
@ यिहुदा काटज़ को पास करने के बजाय this, आप अपने संदर्भ में पारित कर सकते हैं। उदाहरण के लिए, जैसे कि में पारित करने के लिए अतिरिक्त डेटा को परिभाषित करें {new_variable: some_data}?
त्रि गुयेन

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

2
हैंडलबार्स का कौन सा संस्करण इसका समर्थन करता है? मैं १.३.० का उपयोग कर रहा हूँ और यह एक संकलित त्रुटि है जब json के माध्यम से पास करने की कोशिश कर रहा है{{> partialName {new_variable: some_data} }}
bafromca

1
@bafromca सटीक समस्या है कि आप मनमाने ढंग से डेटा पारित नहीं कर सकते, लेकिन केवल एक ही वस्तु। इसलिए आप या तो इसे पास करते हैं या आप एक नई प्रॉपर्टी बनाते हैं जो कंट्रोलर या व्यू में आपके जोंस-डेटा को लौटा देती है। मैं दूसरी बात यह है कि के रूप में आंशिक करने के लिए मनमाना डेटा पारित करना संभव होना चाहिए key=value। क्या गितुब में इसे कवर करने का कोई मुद्दा है?
ओहसीबी

18

बस के मामले में, यहाँ है कि मैंने आंशिक तर्क प्राप्त करने के लिए क्या किया, किस तरह का। मैंने थोड़ा सहायक बनाया है जो आंशिक नाम लेता है और मापदंडों का एक हैश जो आंशिक रूप से पास किया जाएगा:

Handlebars.registerHelper('render', function(partialId, options) {
  var selector = 'script[type="text/x-handlebars-template"]#' + partialId,
      source = $(selector).html(),
      html = Handlebars.compile(source)(options.hash);

  return new Handlebars.SafeString(html);
});

यहां महत्वपूर्ण बात यह है कि रूबलेयर्स मददगार रूबी की तरह तर्कों को स्वीकार करते हैं । सहायक कोड में वे फ़ंक्शन के अंतिम तर्क के भाग के रूप में आते हैं options- - इसके hashसदस्य में। इस तरह आप पहले तर्क प्राप्त कर सकते हैं - आंशिक नाम - और उसके बाद डेटा प्राप्त कर सकते हैं।

फिर, आप शायद Handlebars.SafeStringसहायक से वापस लौटना चाहते हैं या "ट्रिपल” स्टैश "का उपयोग करना चाहते हैं - {{{- इसे दोहरे भागने से रोकने के लिए।

यहाँ अधिक या कम पूर्ण उपयोग परिदृश्य है:

<script id="text-field" type="text/x-handlebars-template">
  <label for="{{id}}">{{label}}</label>
  <input type="text" id="{{id}}"/>
</script>

<script id="checkbox-field" type="text/x-handlebars-template">
  <label for="{{id}}">{{label}}</label>
  <input type="checkbox" id="{{id}}"/>
</script>

<script id="form-template" type="text/x-handlebars-template">
  <form>
    <h1>{{title}}</h1>
    {{ render 'text-field' label="First name" id="author-first-name" }}
    {{ render 'text-field' label="Last name" id="author-last-name" }}
    {{ render 'text-field' label="Email" id="author-email" }}
    {{ render 'checkbox-field' label="Private?" id="private-question" }}
  </form>
</script>

आशा है कि यह मदद करता है ... कोई। :)


15

यह बहुत संभव है यदि आप अपना सहायक लिखें। हम $इस प्रकार की सहभागिता (और अधिक) को पूरा करने के लिए एक कस्टम सहायक का उपयोग कर रहे हैं :

/*///////////////////////

Adds support for passing arguments to partials. Arguments are merged with 
the context for rendering only (non destructive). Use `:token` syntax to 
replace parts of the template path. Tokens are replace in order.

USAGE: {{$ 'path.to.partial' context=newContext foo='bar' }}
USAGE: {{$ 'path.:1.:2' replaceOne replaceTwo foo='bar' }}

///////////////////////////////*/

Handlebars.registerHelper('$', function(partial) {
    var values, opts, done, value, context;
    if (!partial) {
        console.error('No partial name given.');
    }
    values = Array.prototype.slice.call(arguments, 1);
    opts = values.pop();
    while (!done) {
        value = values.pop();
        if (value) {
            partial = partial.replace(/:[^\.]+/, value);
        }
        else {
            done = true;
        }
    }
    partial = Handlebars.partials[partial];
    if (!partial) {
        return '';
    }
    context = _.extend({}, opts.context||this, _.omit(opts, 'context', 'fn', 'inverse'));
    return new Handlebars.SafeString( partial(context) );
});

1
पारित तर्कों तक पहुंच के लिए, आपको उन्हें 'हैश' ऑब्जेक्ट: {{hash.foo}} में देखने की आवश्यकता है। (मैं हैंडलबार के साथ नया हूं और मुझे यह पता लगाने में थोड़ा समय लगा) - धन्यवाद, महान सहायक!
क्लाउडियो ब्रेडफेल्ट

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

@ क्या आप उस सहायक को साझा कर सकते हैं? :)
टॉम

1
@ टॉम, यहाँ यह है (यह अच्छी तरह से प्रारूप करने के लिए कैसे समझ नहीं सकता है, माफ करना): hbs.registerPartials(path.join(__dirname, '/views/partials'), function() { utils.precompileHandlebarsPartials(hbs); }); // Pre compile the partials precompileHandlebarsPartials : function(hbs) { var partials = hbs.handlebars.partials; for (var partial in partials) { if (typeof partials[partial] === 'string') { partials[partial] = hbs.handlebars.compile(partials[partial]); } }; }
Dan

@Dan शायद अपने जवाब के रूप में इसे जोड़ने के लिए बेहतर है।
एलेक्स

14

यह key=valueसंकेतन का उपयोग करते हुए हैंडलबार के बाद के संस्करणों में भी किया जा सकता है :

 {{> mypartial foo='bar' }}

आपको अपने आंशिक संदर्भ में विशिष्ट मूल्यों को पारित करने की अनुमति देना।

संदर्भ: आंशिक # 182 के लिए अलग संदर्भ


1
यह संस्करण 192 में v2.0.0 अल्फा
केविन बॉर्डर्स

9

स्वीकृत उत्तर बहुत अच्छा काम करता है अगर आप अपने हिस्से में एक अलग संदर्भ का उपयोग करना चाहते हैं। हालाँकि, यह आपको किसी भी मूल संदर्भ को संदर्भित नहीं करने देता। कई तर्कों में पास होने के लिए, आपको अपना सहायक लिखना होगा। यहां हैंडलबार्स के लिए काम करने वाला सहायक 2.0.0(संस्करणों के लिए अन्य उत्तर काम करता है <2.0.0):

Handlebars.registerHelper('renderPartial', function(partialName, options) {
    if (!partialName) {
        console.error('No partial name given.');
        return '';
    }
    var partial = Handlebars.partials[partialName];
    if (!partial) {
        console.error('Couldnt find the compiled partial: ' + partialName);
        return '';
    }
    return new Handlebars.SafeString( partial(options.hash) );
});

फिर अपने टेम्पलेट में, आप कुछ ऐसा कर सकते हैं:

{{renderPartial 'myPartialName' foo=this bar=../bar}}

और आपके आंशिक में, आप उन मूल्यों को संदर्भ के रूप में एक्सेस कर पाएंगे:

<div id={{bar.id}}>{{foo}}</div>

मैंने इस संस्करण को हैंडलबार्स 1.0.0 के साथ आज़माया है और यह त्रुटिपूर्ण काम करता है।
क्रिस्टोफर लोर्केन

यह आंशिक नाम '...' के लिए 'खोज' कहाँ करता है?
kemagezien

8

लगता है कि आप ऐसा कुछ करना चाहते हैं:

{{> person {another: 'attribute'} }}

येहुदा ने आपको पहले से ही ऐसा करने का एक तरीका दिया है:

{{> person this}}

लेकिन स्पष्ट करने के लिए:

अपना आंशिक डेटा देने के लिए, मौजूदा मॉडल के अंदर अपना मॉडल दें, जैसे:

{{> person this.childContext}}

दूसरे शब्दों में, यदि यह वह मॉडल है जो आप अपने टेम्पलेट को दे रहे हैं:

var model = {
    some : 'attribute'
}

फिर आंशिक में दी जाने वाली एक नई वस्तु जोड़ें:

var model = {
    some : 'attribute',
    childContext : {
        'another' : 'attribute' // this goes to the child partial
    }
}

childContextयेहुदा ने कहा कि आंशिक के संदर्भ में कहा जाता है - उस में, यह केवल क्षेत्र देखता है another, लेकिन यह नहीं देखता (या क्षेत्र के बारे में परवाह some)। यदि आप idशीर्ष स्तर के मॉडल में थे, और idचाइल्ड कॉंटेक्स्ट में फिर से दोहराएं, तो यह ठीक काम करेगा क्योंकि आंशिक केवल देखता है कि अंदर क्या है childContext



1

यकीन नहीं होता कि यह मददगार है, लेकिन यहाँ इनलाइन RadioButtons आंशिक और क्लाइंट (ब्राउज़र) कंटेनर में रेडियो बटन रेंडर करने के लिए पारित डायनामिक मापदंडों के साथ हैंडलबार्स टेम्पलेट का एक उदाहरण है।

मेरे उपयोग के लिए यह सर्वर पर हैंडलबार्स के साथ प्रदान किया गया है और क्लाइंट को इसे पूरा करने देता है। इसके साथ एक फॉर्म टूल बिना हेल्पर्स के हैंडलबार के भीतर इनलाइन डेटा प्रदान कर सकता है।

नोट: इस उदाहरण के लिए jQuery की आवश्यकता है

{{#*inline "RadioButtons"}}
{{name}} Buttons<hr>
<div id="key-{{{name}}}"></div>
<script>
  {{{buttons}}}.map((o)=>{
    $("#key-{{name}}").append($(''
      +'<button class="checkbox">'
      +'<input name="{{{name}}}" type="radio" value="'+o.value+'" />'+o.text
      +'</button>'
    ));
  });
  // A little test script
  $("#key-{{{name}}} .checkbox").on("click",function(){
      alert($("input",this).val());
  });
</script>
{{/inline}}
{{>RadioButtons name="Radio" buttons='[
 {value:1,text:"One"},
 {value:2,text:"Two"}, 
 {value:3,text:"Three"}]' 
}}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.