web-dev-qa-db-fra.com

guidon - est-il possible d'accéder au contexte parent de manière partielle?

J'ai un modèle de guidon qui charge un partiel pour un sous-élément.

J'aurais besoin d'accéder à une variable à partir du contexte parent dans le modèle d'appel, à partir du partiel. .. Ne semble pas résoudre quoi que ce soit à l'intérieur du partiel.

Le code simplifié va comme ceci:

le modèle

    {{#each items}} 
        {{> item-template}}
    {{/each}}

le partiel

    value is {{value}}

(évidemment le vrai code est plus compliqué mais c'est le même principe, dans le partiel .. ne semble pas être défini.)


Pour montrer qu'il n'est pas défini, j'ai utilisé un assistant très simple whatis comme ceci:

Handlebars.registerHelper('whatis', function(param) {
    console.log(param);
});

et mis à jour le code ci-dessus pour ceci:

modèle mis à jour

    {{#each items}} 
        {{whatis ..}}  <-- Console shows the correct parent context
        {{> item-template}}
    {{/each}}

mise à jour partielle

    {{whatis ..}}  <-- Console shows "undefined"
    value is {{value}}

Y a-t-il un moyen de contourner ce problème? Suis-je en train de manquer quelque chose?

EDIT: Il y a un problème ouvert concernant cette question sur projet github du guidon

57
Ben

Juste au cas où quelqu'un tomberait sur cette question. Cette fonctionnalité existe désormais dans les guidons.

Faites ceci:

{{#each items}} 
    {{! Will pass the current item in items to your partial }}
    {{> item-template this}} 
{{/each}}
39
James Andres

Violon de travail (inspiré par la demande de tirage de guidon # 385 par AndrewHenderson) http://jsfiddle.net/QV9em/4/

Handlebars.registerHelper('include', function(options) {
    var context = {},
        mergeContext = function(obj) {
            for(var k in obj)context[k]=obj[k];
        };
    mergeContext(this);
    mergeContext(options.hash);
    return options.fn(context);
});

Voici comment configurer le modèle parent:

{{#each items}} 
    {{#include parent=..}}
        {{> item-template}}
    {{/include}}
{{/each}}

Et le partiel:

value is {{parent}}
22
pward123

Depuis 2.0.0 les partiels prennent désormais en charge la transmission des valeurs .

{{#each items}}
    {{> item-template some_parent_var=../some_parent_var}}
{{/each}}

Cela m'a pris un certain temps pour trouver cela, j'espère que c'est utile pour quelqu'un d'autre aussi!

10
SeanWM

Le moyen le plus simple de passer le contexte parent au partiel est de faire la boucle à l'intérieur du partiel. De cette façon, le contexte parent est passé par défaut et lorsque vous faites la boucle à l'intérieur du partiel, le {{../variable}} la convention peut accéder au contexte parent.

exemple de violon ici .

Les données

{
  color: "#000"
  items: [
    { title: "title one" },
    { title: "title two" },
  ]
}

Le modèle

<div class="mainTemplate">
  Parent Color: {{color}}
  {{> partial}}
</div>

Le Partiel

<div>
  {{#each items}}
    <div style="color:{{../color}}">
      {{title}}
    </div>
  {{/each}}
</div>
4
StefanHayden

Vous pouvez utiliser certaines des solutions proposées sur les commentaires du lien vers github:

https://github.com/wycats/handlebars.js/issues/182#issuecomment-4206666
https://github.com/wycats/handlebars.js/issues/182#issuecomment-4445747

Ils créent des assistants pour transmettre les informations au partiel.

3
Ricardo Souza

J'ai créé une fonction Helper qui inclut la clé/les valeurs parent dans le sous-contexte sous la clé parentContext.

http://jsfiddle.net/AndrewHenderson/kQZpu/1/

Remarque: le soulignement est une dépendance.

Handlebars.registerHelper('eachIncludeParent', function ( context, options ) {
var fn = options.fn,
    inverse = options.inverse,
    ret = "",
    _context = [];
    $.each(context, function (index, object) {
        var _object = $.extend({}, object);
        _context.Push(_object);
    });
if ( _context && _context.length > 0 ) {
    for ( var i = 0, j = _context.length; i < j; i++ ) {
        _context[i]["parentContext"] = options.hash.parent;
        ret = ret + fn(_context[i]);
    }
} else {
    ret = inverse(this);
}
return ret;

});

À utiliser comme suit:

{{#eachIncludeParent context parent=this}}
    {{> yourPartial}}
{{/eachIncludeParent}}

Accédez aux valeurs de contexte parent dans votre partiel à l'aide de {{parentContext.value}}

2
AndrewHenderson

J'avais besoin d'attributs de formulaire dynamiques pour quelque chose comme ça ...

    {{#each model.questions}}
      <h3>{{text}}</h3>

          {{#each answers}}
                {{formbuilder ../type id ../id text}}
            {{/each}}

    {{/each}}

et une aide comme ça ...

    Handlebars.registerHelper('formbuilder', function(type, id, qnum, text, options)
    {
        var q_type = options.contexts[0][type],
            a_id = options.contexts[1].id,
            q_number = options.contexts[0][qnum],
            a_text = options.contexts[1].text;


            return new Handlebars.SafeString(
                    '<input type=' + q_type + ' id=' + a_id + ' name=' + q_number + '>' + a_text + '</input><br/>'
            );
    });

Ce qui produit ...

<input type="checkbox" id="1" name="surveyQ0">First question</input>

Mon modèle est un gros tas de tableaux et d'objets mélangés. Ce qui est remarquable, c'est que l'utilisation de '../' comme ça '../type' passe dans le modèle parent comme contexte, et sans lui, comme avec 'id', il passe dans le modèle actuel comme contexte.

0
nullsteph