raw opts node hbs handlebars example javascript html handlebars.js templating

javascript - opts - Pasar variables a través de manillares parciales



handlebars raw (7)

Esto es muy posible si escribe su propio ayudante. Estamos utilizando un $ helper personalizado para lograr este tipo de interacción (y más):

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

Actualmente me ocupo de handlebars.js en una aplicación express.js. Para mantener las cosas modulares, dividí todas mis plantillas en parciales.

Mi problema : no pude encontrar una forma de pasar variables a través de una invocación parcial. Digamos que tengo un parcial que se ve así:

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

Supongamos que registré este parcial con el nombre ''myPartial''. En otra plantilla, puedo decir algo como:

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

Esto funciona bien, el parcial se representará como se espera y soy un desarrollador feliz. Pero lo que ahora necesito es una forma de pasar diferentes variables a través de esta invocación, para verificar dentro de un parcial, por ejemplo, si se da un título o no. Algo como:

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

Y la invocación debería verse más o menos así:

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

más o menos.

Sé que puedo definir todos los datos que necesito antes de representar una plantilla. Pero necesito una forma de hacerlo, como acabo de explicar. ¿Hay alguna manera posible?


Esto también se puede hacer en versiones posteriores de manillares utilizando la notación key=value :

{{> mypartial foo=''bar'' }}

Permitiéndole pasar valores específicos a su contexto parcial.

Referencia: contexto diferente para el parcial # 182


La respuesta aceptada funciona muy bien si solo quiere usar un contexto diferente en su parcial. Sin embargo, no le permite hacer referencia al contexto principal. Para pasar múltiples argumentos, necesita escribir su propio ayudante. Aquí hay un ayudante de trabajo para Handlebars 2.0.0 (la otra respuesta funciona para las versiones <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) ); });

Luego, en su plantilla, puede hacer algo como:

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

Y en su parcialidad, podrá acceder a esos valores en un contexto como:

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


Los parciales de manillar toman un segundo parámetro que se convierte en el contexto para el parcial:

{{> person this}}

En las versiones v2.0.0 alpha y posteriores, también puede pasar un hash de parámetros con nombre:

{{> person headline=''Headline''}}

Puede ver las pruebas para estos escenarios: 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


Parece que quieres hacer algo como esto:

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

Yehuda ya te dio una manera de hacer eso:

{{> person this}}

Pero para aclarar:

Para dar a su parcial sus propios datos, simplemente déle su propio modelo dentro del modelo existente, así:

{{> person this.childContext}}

En otras palabras, si este es el modelo que le está dando a su plantilla:

var model = { some : ''attribute'' }

A continuación, agregue un nuevo objeto para dar al parcial:

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

childContext convierte en el contexto de lo parcial, como dijo Yehuda: en eso, solo ve el campo como another , pero no ve (o le importa un poco el campo). Si tenía una id en el modelo de nivel superior y repite la id nuevamente en el childContext, eso funcionará bien ya que el parcial solo ve lo que hay dentro de childContext .


Por las dudas, esto es lo que hice para obtener argumentos parciales, más o menos. Creé un pequeño ayudante que toma un nombre parcial y un hash de parámetros que se pasarán al parcial:

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

La clave aquí es que los ayudantes de Handlebars aceptan un hash de argumentos tipo Ruby . En el código auxiliar, se incluyen como parte de las últimas options argumento de la función en su miembro hash . De esta forma, puede recibir el primer argumento, el nombre parcial, y obtener los datos después de eso.

Entonces, es probable que desee devolver Handlebars.SafeString del helper o usar "triple-stash" - {{{ - para evitar que doble escape.

Aquí hay un escenario de uso más o menos completo:

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

Espero que esto ayude a alguien. :)