web-dev-qa-db-fra.com

Chargement dynamique des modèles dans Meteor.js

J'aimerais pouvoir charger des modèles de manière dynamique sans spécifier explicitement le modèle.

Par exemple:

<template name="foo">
</template>

où 'foo' est le modèle, j'aimerais pouvoir le charger dynamiquement en appelant une méthode:

Meteor.render(Meteor.loadTemplate('foo'));

Est-ce possible?

20
chimon2000

Nouvelle API Meteor 0.9.x

Dan Dascalescu a souligné que Meteor a maintenant des modèles dynamiques intégrés! C'est bien parce que vous n'avez pas besoin d'inclure le code supplémentaire comme dans les versions précédentes.

{{> Template.dynamic template=template [data=data] }}

Pour Meteor 0.8.x Legacy

Modèle dynamique Sans Données: La réponse mise à jour de Blaze (0.8.0) de Boris Kotov est sur la bonne voie (tirée des derniers documents), mais elle ne fonctionne pas telle quelle pour moi. J'ai le travail suivant:

{{> dynamicTemplate name=myDynName}}

<template name="dynamicTemplate">
    {{#with chooseTemplate name}}
        {{> template}}
   {{/with}}
</template>

Template.dynamicTemplate.chooseTemplate = function (name) {
    return { template: Template[name] };
};

J'espère qu'il existe une solution plus simple, mais je devais envelopper le modèle dans un fichier JSON, comme indiqué. Cela aidera peut-être quelqu'un d'autre à aller de l'avant.

Modèle dynamique Avec Données: Si vous avez et souhaitez que les données soient dynamiques, assurez-vous de créer une méthode d'assistance qui peut réagir. Assurez-vous de faire un Session.set () quelque part pour voir l’effet.

// Inside "myContainingTemplate"
{{> dynamicTemplateWithData name=myDynName data=myDataHelper}}

<template name="dynamicTemplateWithData">
    {{#with chooseTemplate name}}
        {{#with ../data}}
            {{> ..}}
        {{/with}}
    {{/with}}
</template>

Template.dynamicTemplateWithData.chooseTemplate = function (name) {
    return Template[name];
};

Template.myContainingTemplate.helpers({
    myDataHelper: function () {
        Session.get('myReactiveKey');
    }
});
13
Turbo

Voici comment rendre dynamiquement les modèles, à partir de Meteor 0.9.4 - 1.0. Toutes les autres réponses étaient obsolètes au moment d'écrire ces lignes.

Supposons que vous modifiez plusieurs enregistrements ou que vous en créez un nouveau et que vous souhaitez restituer le modèle update ou le modèle new en fonction de certaines variables de session.

Il y a deux façons de faire ça:

1) C’est la méthode officiellement recommandée pour Meteor 0.9.4 ou plus récent - il utilise Template.dynamic :

<template name="records">
  {{> Template.dynamic template=whichOne}}
</template>

<template name="recordUpdate">
  ...
</template>

<template name="recordNew">
  ...
</template>

Template.records.helpers({
  whichOne: function () {
    return Session.get('edit') ? 'recordUpdate' : 'recordNew'
    // note that we return a string - per http://docs.meteor.com/#template_dynamic
  }
});

2) Cela fonctionne dans différentes versions de Meteor, mais n'est pas recommandé officiellement car il n'est pas clair que le modèle soit choisi de manière dynamique:

<template name="records">
  {{> whichOne}}
</template>

{{! Note how "whichOne" is indistinguishable from a constant template name... }}
{{  ...like "recordUpdate" or "recordNew" below. }}

<template name="recordUpdate">
  ...
</template>

<template name="recordNew">
  ...
</template>

Template.records.helpers({
  whichOne: function () {
    return Session.get('edit') ? Template.recordUpdate : Template.recordNew
    // note that we return a Template object, not a string
  }
});

Pour transmettre un contexte de données au modèle, utilisez:

{{> Template.dynamic template=whichOne data=myData}}
36
Dan Dascalescu

Vous avez trouvé Meteor.render mais ce qui vous manque, c'est le chargement du modèle . Dans la documentation, il est mentionné que vous pouvez appeler Template.foo () pour renvoyer le code HTML d'un modèle.

http://docs.meteor.com/#template_call

En regroupant ces éléments, vous accédez au modèle foo ou à un autre en utilisant l’accès au support de manière à:

var templateName = "foo";
var fragment = Meteor.render( function() {
    return Template[ templateName ](); // this calls the template and returns the HTML.
});

Ensuite, fragment est votre fragment réactif, de sorte que votre modèle puisse continuer à recevoir des mises à jour en direct. Votre fragment a maintenant besoin d'être placé dans la page Web (j'utilise jQuery, donc cet exemple aussi):

$("#htmlnode").html( fragment );

$ ("# htmlnode") est juste un noeud de votre DOM où vous voulez que le modèle soit rendu. Et vous avez maintenant le contenu rendu dans votre page Web.

7
Joc

Je le fais juste comme ça, pas besoin de jQuery:

&EACUTE;DIT&EACUTE;

Template.mainContent.showContentFromRouter = function() {
    return Template[Meteor.Router.page()]();
};

Dans ce cas, j'utilise le routeur Meteor et renvoie le modèle que je choisis (depuis le routeur), mais vous pouvez le faire:

Template.mainContent.showDynamicContent = function() {
    return Template['someTemplateYouveDefined']();
};
2
Kristoffer K

Mise à jour pour blaze:

https://github.com/meteor/meteor/wiki/Using-Blaze#templatefoo-is-not-a-function-and-does-not-return-a-string

Rendre dynamiquement un modèle avec un contexte de données donné

Vieux:

{{dynamicTemplate name="templateName" data=dataContext}}

Template.foo.dynamicTemplate = function (opts) {
  return Template[opts.name](opts.data);
};

Nouveau: (notamment dans Blaze, les arguments de mot clé d'inclusion ou d'aide au blocage sont regroupés dans un seul objet qui devient le nouveau contexte de données)

{{> dynamicTemplate name="templateName" data=dataContext}}

<template name="dynamicTemplate">
  {{#with chooseTemplate name}}
    {{#with ../data}}  {{! original 'data' argument to DynamicTemplate}}
      {{> ..}}         {{! return value from chooseTemplate(name) }}
    {{/with}}
  {{/with}}
</template>

Template.dynamicTemplate.chooseTemplate = function (name) {
  return Template[name];
}

En passant, je ne joue pas vraiment avec, mais c’est ce que j’ai tiré des nouvelles documentations Blaze. Donc je pense que ça devrait être la façon de le faire;)

2
Boris Kotov

De https://github.com/meteor/meteor/wiki/Using-Blaze

{{> post}}

Template.foo.helpers({
  post: function () {
    return Template[this.postName];
  }
});

Les inclusions de modèles recherchent désormais dans les espaces de noms des assistants et des données des objets de modèle, ce qui facilite le choix du modèle à utiliser par programme. C’est une fonctionnalité puissante qui autorise des modèles tels que l’affectation d’un modèle à l’aide d’un autre afin qu’il puisse être remplacé.

0
Bernát

Meteor 0.8.x Legacy

En utilisant Joc's answer comme guide, J'ai obtenu des résultats similaires en utilisant http://docs.meteor.com/#template_call , mais en utilisant plutôt une aide, comme suggéré par la documentation:

Appelé à l'intérieur d'un assistant de modèle, du corps de Meteor.render ou d'autres paramètres dans lesquels un code HTML réactif est généré, le code HTML résultant est annoté de sorte qu'il s'affiche sous forme d'éléments DOM réactifs.

Mon client.js ressemble un peu à ceci:

Template.myPageTemplate.helpers({
  dynamicTemplate: function() {
    // conditional logic can be added here to determine which template to render
    return Template.myDynamicTemplate();
  }
});

et mon html ressemble à ceci:

<template name="myPageTemplate">
  <h1>My Template</h1>
  {{{dynamicTemplate}}}
</template>

<template name="myDynamicTemplate">
  <h1>My Dynamic Template</h1>
</template>
0
hillmark