Wie führe ich ein if / else in mustache.js durch?

258

Es scheint ziemlich seltsam, dass ich nicht herausfinden kann, wie man das mit dem Schnurrbart macht. Wird es unterstützt?

Dies ist mein trauriger Versuch:

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

Dies ist offensichtlich nicht richtig, aber in der Dokumentation wird so etwas nicht erwähnt. Das Wort "sonst" wird nicht einmal erwähnt :(

Warum ist Schnurrbart so gestaltet? Wird so etwas als schlecht angesehen? Versucht es mich zu zwingen, den Standardwert im Modell selbst festzulegen? Was ist mit den Fällen, in denen das nicht möglich ist?

egervari
quelle
1
"Warum ist Schnurrbart so gestaltet?" Ich bin mir nicht sicher, aber ich denke, die Idee ist, dass eine Vorlagensprache genau das sein sollte: eine Sprache zum Schreiben von Vorlagen, dh Dinge, die wie die von ihnen erzeugte Ausgabe aussehen, nur mit Löchern, in die die variablen Bits gehen. Wenn Sie Logik in die Vorlagensprache einfügen, werden die Vorlagen komplizierter. Wenn Sie bereits eine Programmiersprache für die Verarbeitung der Logikbits haben, warum dann?
Paul D. Waite
4
@ PaulD.Waite "Logic-less" bedeutet wirklich "nicht willkürlicher Code", denke ich. Es ist genauso schlecht, echte Ansichtslogik in Code einzufügen, wie Nicht-Ansichtslogik in eine Vorlage einzufügen. Moustache versucht, eine absolute Logik bereitzustellen, um dies zu erreichen.
jpmc26
2
Oder verwenden Sie Lenker anstelle von Schnurrbart. In der Lage zu sein zu schreiben, z. B. {{#each items}}{{#unless @first}}Output comma before 2nd, 3rd, 4th...{{/unless}}{{/each}}ist lesbarer, viel sauberer und ist immer noch Präsentation. "Logic-less" ist eine Richtlinie, es muss keine Zwangsjacke sein.
Skifahrerseite
Vielleicht ist es keine ausreichend vielseitige Template-Engine, wenn ein OP sagt "das ist mein trauriger Versuch, [...] das ist offensichtlich nicht richtig" ... und dann ist die akzeptierte Antwort das Kopieren und Einfügen dieses Codes :). Kein Urteil über OP oder Antwort; gerade aufmustache
dwanderson

Antworten:

498

So geht's, wenn / else in Moustache (perfekt unterstützt):

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

Oder in Ihrem Fall:

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

Suchen Sie in den Dokumenten nach invertierten Abschnitten: https://github.com/janl/mustache.js

Eneko Alonso
quelle
89
Die Schnurrbart-Dokumente sind urkomisch. "Wir nennen es" logiklos ", weil es keine if-Anweisungen, else-Klauseln oder for-Schleifen gibt." Yeeeeaaaaaa ....
Boxed
6
@boxed, technisch gesehen haben Sie Recht, der invertierte Abschnitt ist eine logische Anweisung, da er den Tag-Wert überprüft. Ich denke jedoch, dass die Nuance hier darin besteht, dass beide Aussagen explizit bewertet werden müssen und nicht nur ein einziges if / else. Grundsätzlich erzwingt der Schnurrbart die Struktur, if (condition){ //do something}gefolgt von a if (!condition){//do something else}. Außerdem ist die Menge an Logik, die man in Logik ausführen kann, im Vergleich zu einer logikbasierten Sprache extrem reduziert. Existenz oder Nichtexistenz sind die einzigen Prüfungen, dh Sie können nicht prüfen, ob der Wert eines Tags gleich 5 ist, und dann in den Code dieses Tags fallen.
MandM
22
@ MandM ja ... also hat es Logik, aber es kann einfach nichts Nützliches tun: P
Boxed
Es hält Sie nur davon ab, sich mit der Logik zu beschäftigen. Viele verschachtelte if / else in einem anderen if / else zu haben, ist ein Zeichen für falsches Design
Tebe
@boxed können Sie für Schleife mit moustache.js (mindestens ngFor-ish Schleife)
tun
54

Dies lösen Sie im "Controller", dem Punkt des logischen Templating.

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

}

Dies ist tatsächlich viel besser als das Verwalten von Bild-URLs oder anderen Medien, die sich in Ihren Vorlagen möglicherweise ändern oder nicht, aber gewöhnungsbedürftig sind. Der Punkt ist, das Tunneln von Vorlagentunneln zu verlernen. Eine Avatar-IMG-URL muss in anderen Vorlagen verwendet werden. Werden Sie diese URL in X-Vorlagen oder einem einzelnen DEFAULTS-Einstellungsobjekt beibehalten? ;)

Eine andere Möglichkeit besteht darin, Folgendes zu tun:

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

Und in der Vorlage:

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

Aber das widerspricht der ganzen Bedeutung von logischem Templating. Wenn du das willst, willst du logisches Templating und du solltest Moustache nicht verwenden, aber gib ihm selbst eine faire Chance, dieses Konzept zu lernen;)

BGerrissen
quelle
Vielen Dank. Das ist eine großartige Antwort! Es hat mir auch bei anderen strukturellen Aspekten geholfen, wie man Dinge in der Struktur des Javascript-Codes erledigt.
Egervari
{{/ # hasAvatar}} und {{/ # noAvatar}} sollten in dieser Antwort {{/ hasAvatar}} und {{/ noAvatar}} sein.
Mulhoon
14

Ihre else- Anweisung sollte folgendermaßen aussehen (beachten Sie Folgendes ^):

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

Im Schnurrbart wird dies als "umgekehrte Abschnitte" bezeichnet.

anonym
quelle
7
Beachten Sie, dass Sie nicht sowohl # als auch ^ benötigen, sondern nur ^ für den Fall 'nicht'
zappan
Das funktioniert in der neuesten Version nicht. Zappan ist richtig, Sie brauchen nur die ^
Simonmorley
0

Sie können einen Helfer in der Ansicht definieren. Die bedingte Logik ist jedoch etwas eingeschränkt. Moxy-Stencil ( https://github.com/dcmox/moxyscript-stencil ) scheint dies mit "parametrisierten" Helfern zu beheben, z.

{{isActive param}}

und in der Ansicht:

view.isActive = Funktion (Pfad: Zeichenfolge) {Rückgabepfad === this.path? "class = 'active'": ''}

Daniel
quelle
0

Beachten Sie, dass Sie {{.}}das aktuelle Kontextelement rendern können.

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

{{^avatar}}missing{{/avatar}}
Hafthor
quelle