Comment réaliser un if / else dans moustache.js?

258

Il semble plutôt étrange que je ne puisse pas comprendre comment faire cela avec la moustache. Est-il pris en charge?

Ceci est ma triste tentative d'essayer:

    {{#author}}
      {{#avatar}}
        <img src="{{avatar}}"/>
      {{/avatar}}
      {{#!avatar}}
        <img src="/images/default_avatar.png" height="75" width="75" />
      {{/avatar}}
    {{/author}}

Ce n'est évidemment pas vrai, mais la documentation ne mentionne rien de semblable. Le mot "else" n'est même pas mentionné :(

Aussi, pourquoi la moustache est-elle conçue de cette façon? Ce genre de chose est-il considéré comme mauvais? Essaie-t-il de me forcer à définir la valeur par défaut dans le modèle lui-même? Qu'en est-il des cas où cela n'est pas possible?

egervari
la source
1
"pourquoi la moustache est-elle conçue de cette façon?" Je ne suis pas trop sûr, mais je pense que l'idée est qu'un langage de modélisation devrait être juste cela: un langage pour écrire des modèles, c'est-à-dire des choses qui ressemblent à la sortie qu'elles produisent, juste avec des trous où vont les bits variables. Mettre la logique dans le langage de modèle rend les modèles plus compliqués, et quand vous avez déjà un langage de programmation pour gérer les bits logiques, pourquoi s'embêter?
Paul D. Waite
4
@ PaulD.Waite «sans logique» signifie vraiment «code non arbitraire», je pense. Il est tout aussi mauvais de mettre de la vraie logique d'affichage dans du code que de mettre de la logique sans vue dans un modèle. Moustache essaie de fournir une logique minimale pour y parvenir.
jpmc26
2
Ou utilisez le guidon au lieu de la moustache. Etre capable d'écrire, par exemple, {{#each items}}{{#unless @first}}Output comma before 2nd, 3rd, 4th...{{/unless}}{{/each}}est plus lisible, beaucoup plus propre et reste une présentation. "Logic-moins" est une ligne directrice, il ne doit pas être une camisole de force.
skierpage
Ce n'est peut-être pas un moteur de modélisation suffisamment polyvalent lorsqu'un OP dit "c'est ma triste tentative [...] ce n'est évidemment pas juste" ... et la réponse acceptée est alors un copier-coller de ce code :). Aucun jugement sur OP ou réponse; just onmustache
dwanderson

Réponses:

498

Voici comment faire si / else dans Moustache (parfaitement pris en charge):

{{#repo}}
  <b>{{name}}</b>
{{/repo}}
{{^repo}}
  No repos :(
{{/repo}}

Ou dans votre cas:

{{#author}}
  {{#avatar}}
    <img src="{{avatar}}"/>
  {{/avatar}}
  {{^avatar}}
    <img src="/images/default_avatar.png" height="75" width="75" />
  {{/avatar}}
{{/author}}

Recherchez les sections inversées dans les documents: https://github.com/janl/mustache.js

Eneko Alonso
la source
89
Les documents de moustache sont hilarants. "Nous l'appelons" sans logique "car il n'y a pas d'instructions if, de clauses else ou de boucles for." Yeeeeaaaaaa ....
boxé
6
@boxed, techniquement vous avez raison, la section inversée est une déclaration logique, car elle vérifie la valeur de la balise. Mais, je pense que la nuance ici est que les deux déclarations doivent être explicitement évaluées, plutôt qu'un seul if / else. Fondamentalement, la moustache force la structure if (condition){ //do something}suivie d'un if (!condition){//do something else}. De plus, la quantité de logique que l'on peut exécuter en logique est extrêmement réduite par rapport à un langage basé sur la logique. L'existence ou la non-existence sont les seules vérifications, c'est-à-dire que vous ne pouvez pas vérifier si la valeur d'une balise est égale à 5, puis tomber dans le code de cette balise.
MandM
22
@MandM oui ... donc il a de la logique mais il ne peut rien faire d'utile: P
boxed
Cela vous empêche de jouer avec la logique if else. Avoir beaucoup de si / autre imbriqués dans un autre si / autre est un signe de mauvaise conception
Tebe
@boxed vous pouvez faire pour la boucle avec moustache.js (au moins la boucle ngFor-ish)
aloisdg passe à codidact.com
54

C'est quelque chose que vous résolvez dans le "contrôleur", qui est le point de modèle sans logique.

// some function that retreived data through ajax
function( view ){

   if ( !view.avatar ) {
      // DEFAULTS can be a global settings object you define elsewhere
      // so that you don't have to maintain these values all over the place
      // in your code.
      view.avatar = DEFAULTS.AVATAR;
   }

   // do template stuff here

}

C'est en fait beaucoup mieux que de maintenir les URL des images ou d'autres médias qui pourraient ou non changer dans vos modèles, mais cela prend un certain temps pour s'y habituer. Le but est de désapprendre la vision du tunnel de modèle, une URL img d'avatar est destinée à être utilisée dans d'autres modèles, allez-vous conserver cette URL sur les modèles X ou un seul objet de paramètres DEFAULTS? ;)

Une autre option consiste à effectuer les opérations suivantes:

// augment view
view.hasAvatar = !!view.avatar;
view.noAvatar = !view.avatar;

Et dans le modèle:

{{#hasAvatar}}
    SHOW AVATAR
{{/hasAvatar}}
{{#noAvatar}}
    SHOW DEFAULT
{{/noAvatar}}

Mais cela va à l'encontre de toute la signification des modèles sans logique. Si c'est ce que vous voulez faire, vous voulez des modèles logiques et vous ne devriez pas utiliser la moustache, mais donnez-vous une bonne chance d'apprendre ce concept;)

BGerrissen
la source
Merci. Voilà une excellente réponse! En fait, cela m'a aussi aidé avec d'autres aspects structurels sur "quand faire des choses" dans la structure du code javascript.
egervari
{{/ # hasAvatar}} et {{/ # noAvatar}} devraient être {{/ hasAvatar}} et {{/ noAvatar}} dans cette réponse.
Mulhoon
14

Votre déclaration else devrait ressembler à ceci (notez le ^):

{{^avatar}}
 ...
{{/avatar}}

Dans la moustache, cela s'appelle «sections inversées».

anonyme
la source
7
notez que vous n'avez pas besoin à la fois de # et ^, c'est juste ^ pour 'pas'
zappan
Cela ne fonctionne pas dans la dernière version. Zappan a raison, vous n'avez besoin que du ^
simonmorley
0

Vous pouvez définir un assistant dans la vue. Cependant, la logique conditionnelle est quelque peu limitée. Moxy-Stencil ( https://github.com/dcmox/moxyscript-stencil ) semble résoudre ce problème avec des assistants "paramétrés", par exemple:

{{isActive param}}

et dans la vue:

view.isActive = function (path: string) {return path === this.path? "class = 'active'": ''}

Daniel
la source
0

Remarque, vous pouvez utiliser {{.}}pour rendre l'élément de contexte actuel.

{{#avatar}}{{.}}{{/avatar}}

{{^avatar}}missing{{/avatar}}
Hafthor
la source