繁体   English   中英

部分通过把手传递变量

[英]Passing variables through handlebars partial

我目前在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>

并且invokation应该看起来像这样:

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

或者。

我知道,在渲染模板之前,我能够定义所需的所有数据。 但我需要一种方法来解决这个问题。 有可能吗?

Handlebars partials采用第二个参数,该参数成为partial的上下文:

{{> person this}}

在版本v2.0.0 alpha及更高版本中,您还可以传递命名参数的哈希:

{{> person headline='Headline'}}

您可以看到这些方案的测试: https//github.com/wycats/handlebars.js/blob/ce74c36118ffed1779889d97e6a2a1028ae61510/spec/qunit_spec.js#L456-L462 https://github.com/wycats/handlebars.js/ BLOB / e290ec24f131f89ddf2c6aeb707a4884d41c3c6d /规格/ partials.js#L26-L32

如果您编写自己的帮助程序,这是非常可能的。 我们使用自定义$ helper来完成这种类型的交互(以及更多):

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

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) );
});

以防万一,这是我做的部分争论,有点。 我创建了一个小助手,它带有一个部分名称和一个将传递给partial的参数哈希:

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);
});

这里的关键是Handlebars助手接受类似Ruby的参数哈希 在辅助代码中,它们作为函数的最后一个参数 - options - 在其hash成员中。 这样,您可以接收第一个参数 - 部分名称 - 然后获取数据。

然后,您可能希望从帮助程序返回Handlebars.SafeString或使用“triple-stash” - {{{ - 以防止它双重转义。

这是一个或多或少完整的使用场景:

<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>

希望这有助于...某人。 :)

这也可以使用key=value表示法在更高版本的把手中完成:

 {{> mypartial foo='bar' }}

允许您将特定值传递给部分上下文。

参考: 部分#182的上下文不同

如果您只是想在部分中使用不同的上下文,那么接受的答案会很有效。 但是,它不允许您引用任何父上下文。 要传递多个参数,您需要编写自己的帮助器。 这是Handlebars 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>

听起来你想做这样的事情:

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

耶胡达已经给你一个这样做的方法:

{{> person this}}

但澄清一下:

为了给你自己的部分数据,只需在现有模型中给它自己的模型,如下所示:

{{> person this.childContext}}

换句话说,如果这是您为模板提供的模型:

var model = {
    some : 'attribute'
}

然后添加一个要赋予partial的新对象:

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

childContext成为部分像耶胡达的背景下说的-在这,它只能看到现场another ,但它并没有看到(或关心的领域some )。 如果你在顶级模型中有id ,并在childContext中再次重复id ,那就可以正常工作,因为partial只能看到childContext里面的childContext

是的,我迟到了,但我可以为Assemble用户添加:你可以使用buil-in "parseJSON"帮助器http://assemble.io/helpers/helpers-data.html (在https://github.com/assemble/assemble/issues/416中发现)。

不确定这是否有用,但这里是Handlebars模板的示例,其中动态参数传递给内联RadioButtons部分,客户端(浏览器)呈现容器中的单选按钮。

对于我的使用,它在服务器上使用Handlebars进行渲染,并让客户端完成它。 有了它,表单工具可以在没有帮助程序的情况下在Handlebars中提供内联数据。

注意:此示例需要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"}]' 
}}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM