Przekazywanie zmiennych przez kierownicę częściowe

Obecnie zajmuję się kierownicą.js w ekspresie.aplikacja js. Aby zachować modułowość, podzieliłem wszystkie szablony na części.

Mój problem: nie mogłem znaleźć sposobu, aby przekazać zmienne przez częściowe wywołanie. Załóżmy, że mam część, która wygląda tak:

<div id=myPartial>
    <h1>Headline<h1>
    <p>Lorem ipsum</p>
</div>
Załóżmy, że zarejestrowałem tę część pod nazwą "myPartial". W innym szablonie mogę wtedy powiedzieć coś w stylu:
<section>
    {{> myPartial}}
</section>

To działa dobrze, część będzie renderowana jako oczekiwany i jestem szczęśliwym deweloperem. Ale to, czego teraz potrzebuję, to sposób przekazywania różnych zmiennych przez to wywołanie, aby sprawdzić w części, na przykład, czy podano nagłówek, czy nie. Coś w stylu:

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

A inwokacja powinna wyglądać mniej więcej tak:

<section>
    {{> myPartial|'headline':'Headline'}}
</section>
Mniej więcej.

Wiem, że jestem w stanie zdefiniować wszystkie potrzebne mi dane, zanim wyrenderuję szablon. Ale potrzebuję sposobu, jak to wyjaśniłem. Jest jakiś możliwy sposób?

Author: alex, 2012-07-17

7 answers

Część kierownicy przyjmuje drugi parametr, który staje się kontekstem dla części:

{{> person this}}

W wersjach v2.0.0 alpha i nowszych, możesz również przekazać hash nazwanych parametrów:

{{> person headline='Headline'}}

Możesz zobaczyć testy dla tych scenariuszy: https://github.com/wycats/handlebars.js/blob/ce74c36118ffed1779889d97e6a2a1028ae61510/spec/qunit_spec.js#L456-L462 https://github.com/wycats/handlebars.js/blob/e290ec24f131f89ddf2c6aeb707a4884d41c3c6d/spec/partials.js#L26-L32

 177
Author: Yehuda Katz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-22 16:01:49

Jest to bardzo możliwe, jeśli napiszesz własnego pomocnika. Do tego typu interakcji (i nie tylko) używamy custom $ helpera:

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

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) );
});
 15
Author: Jesse Houchins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-30 02:52:36

Na wszelki wypadek, oto co zrobiłem, aby uzyskać częściowe argumenty, tak jakby. Stworzyłem mały helper, który pobiera częściową nazwę i hash parametrów, które zostaną przekazane do częściowej:

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

Najważniejsze jest to, że pomocnicy kierownicy akceptują podobny do Ruby hash argumentów. W kodzie pomocniczym są one częścią ostatniego argumentu funkcji - options - w jej członie hash. W ten sposób możesz otrzymać pierwszy argument-nazwę częściową - i uzyskać dane po to.

Następnie prawdopodobnie chcesz zwrócićHandlebars.SafeString z helpera lub użyć "Triple‑stash"-{{{- aby zapobiec podwójnej ucieczce.

Oto mniej lub bardziej kompletny scenariusz użycia:

<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>
Mam nadzieję, że to komuś pomoże. :)
 14
Author: Vlad GURDIGA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-21 16:23:51

Można to również zrobić w późniejszych wersjach kierownicy używając notacji key=value:

 {{> mypartial foo='bar' }}

Pozwalający przekazać określone wartości do częściowego kontekstu.

Odniesienie: kontekst inny dla częściowego #182

 10
Author: cweston,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-08 15:28:44

Brzmi jakbyś chciał zrobić coś takiego:

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

Yehuda już dał ci sposób na to:

{{> person this}}

Ale dla wyjaśnienia:

Aby dać częściowe swoje własne dane, po prostu daj mu swój własny model wewnątrz istniejącego modelu, w ten sposób:

{{> person this.childContext}}

Innymi słowy, jeśli jest to model, który dajesz szablonowi:

var model = {
    some : 'attribute'
}

Następnie dodaj nowy obiekt do części:

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

childContext staje się kontekstem częściowego jak Yehuda powiedział - w tym, widzi tylko pole another, ale nie widzi (lub troszczy się o Pole some). Jeśli masz id w modelu najwyższego poziomu i powtórz id ponownie w childContext, będzie to działać dobrze, ponieważ częściowy widzi tylko to, co jest w środku childContext.

 5
Author: Chunky Bacon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-04 19:56:46

Zaakceptowana odpowiedź działa świetnie, jeśli chcesz użyć innego kontekstu w części. Nie pozwala to jednak odwoływać się do żadnego kontekstu nadrzędnego. Aby przekazać wiele argumentów, musisz napisać własny helper. Oto działający pomocnik dla kierownicy 2.0.0 (druga odpowiedź działa dla wersji <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) );
});

Następnie w szablonie możesz zrobić coś takiego:

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

I w Twojej Części, będziesz mógł uzyskać dostęp do tych wartości jako kontekstu, jak:

<div id={{bar.id}}>{{foo}}</div>
 5
Author: Andrew C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-21 20:06:58

Tak, spóźniłem się, ale mogę dodać dla Assembly użytkowników: możesz użyć Buil-in "parseJSON" helper http://assemble.io/helpers/helpers-data.html . (Odkryte w https://github.com/assemble/assemble/issues/416).

 3
Author: vasiliy0s,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-23 21:11:25