2013-07-14 19 views
12

Qual è il modo migliore per gestire un caso di commutazione in un modello (ad esempio: un pulsante con 4 stati possibili)? Sembra sbagliato a tirare il codice HTML fuori in un aiuto, ma ci si sente proprio così male a mettere la logica nel modello ...Come gestire gli interruttori in modelli Meteor

Edit:

Come si può vedere, mettendo il codice HTML in un l'helper è lontano dall'ideale, ma cambiare classe, nome di tag, proprietà e contenuto renderebbe il template completamente illeggibile.

Template.nextMeetup.helpers({ 
    rsvpButton: function(rsvp) { 
     var button; 

     switch(rsvp){ 
      case 'yes': 
       button = '<a ' + this.event_url + 'class="rsvp btn btn-success pull-right" title="visit event page" target="_blank"><i class="icon-check"></i> I\'m Attending</a>'; 
      break; 
      case 'maybe': 
       button = '<a ' + this.event_url + 'class="rsvp btn btn-warning pull-right" title="visit event page" target="_blank"><i class="icon-warning-sign"></i> I might go</a>'; 
      break; 
      case 'no': 
       button = '<a ' + this.event_url + 'class="rsvp btn btn-danger pull-right" title="visit event page" target="_blank"><i class="icon-remove"></i> I\'m not going</a>'; 
      break; 
      case 'none': 
       button = '<a ' + this.event_url + 'class="rsvp btn btn-inverse pull-right" title="visit event page" target="_blank"><i class="icon-spinner"></i> I havn\'t decided</a>'; 
      break; 
      default: 
       button = '<button class="rsvp signIn btn btn-disabled pull-right">Sign in to RSVP</button>'; 
     } 
     return new Handlebars.SafeString(button); 
    } 
}); 

risposta

11

Non sai cosa stai provando a produrre, ma un helper che valuta l'uguaglianza sarà probabilmente coinvolto. Mettere questo in uno dei file JavaScript client-caricato del vostro progetto:

Template.registerHelper("equals", function (a, b) { 
    return (a == b); 
}); 

quindi è possibile creare qualcosa di simile a una struttura di switch-case utilizzando if blocchi e la nuova equals aiutante. Ad esempio, se si sta memorizzare lo stato di un pulsante in una variabile denominata btnState ei valori possibili sono 1, 2 o 3:

<button class="{{#if equals btnState 1}}btn-active{{/if}} 
       {{#if equals btnState 2}}btn-inactive{{/if}} 
       {{#if equals btnState 3}}btn-disabled 
       {{else}}btn-default{{/if}}"> 

Se volete switch - capacità di corto circuito ulteriormente s' case test dopo colpisce un vero valore, e/o di un caso di default, alla fine, il modo per farlo è con una brutta serie di nidificate if - else blocchi:

<button class="{{#if equals btnState 1}} 
       btn-active 
       {{else}} 
       {{#if equals btnState 2}} 
        btn-inactive 
       {{else}} 
        {{#if equals btnState 3}} 
        btn-disabled 
        {{else}} 
        btn-default 
        {{/if}} 
       {{/if}} 
       {{/if}}"> 

Questo esempio è quasi banalmente semplice; Suppongo che tu stia usando questo come una struttura di controllo per un modello di grandi dimensioni, dove invece di qualcosa come btn-default hai decine di righe di HTML.

Se lo si utilizza davvero per brevi frammenti di testo come i nomi di classi CSS, è possibile invece creare un helper che mappa un set di casi con un set di stringhe da restituire. Per esempio (CoffeeScript):

Template.registerHelper "switch", (input, cases, output, def) -> 
    # input is the variable we're comparing, i.e. switch(input) 
    # cases is an EJSON-stringified array, i.e. case "foo", case "bar" 
    # output is an EJSON-stringified array of strings to return for each case 
    # def (default) is a string to return if none of the cases are met 

    # Validate input, convert EJSON strings into arrays: 
    unless input? and _.isString(cases) and _.isString(output) 
    return "" 
    cases = EJSON.parse cases 
    output = EJSON.parse output 
    unless _.isArray(cases) and _.isArray(output) and 
    cases.length is output.length 
     return "" 

    # Evaluate each case, returning as soon as the first case is true: 
    for value, index in cases 
    return output[index] if input is value 

    # If we've made it this far, none of the cases were met; return def (default): 
    if def? and _.isString(def) then return def else return "" 

E usarlo:

{{switch btnState "[1,2,3]" 
    "[\"btn-active\",\"btn-inactive\",\"btn-disabled\"]" "btn-default"}} 

Manubri non consente matrici anabbagliante o oggetti in aiutanti, quindi i contorsioni con stringhe JSON passate come parametri e quindi analizzati.

+1

Grazie per la risposta approfondita, ma come temevo la risposta sembra essere: non c'è un buon modo :(L'if/else/switch nel mezzo del modello sembra già piuttosto disordinato, e questo è con solo una singola modifica delle proprietà (intendo classi, proprietà e contenuto). Il "commutatore" sembra più ragionevole, ma sembra fragile e artificioso. Credo che speravo che esistesse una pratica comune per gestire qualcosa di simile. – Sinetheta

+3

È ancora possibile separare il contenuto dalla logica. Puoi creare una serie di sottotasti (parziali) per ciascuno dei tuoi pulsanti. Quindi se vuoi usare il tuo helper, sostituisci le stringhe HTML con 'Template.btnYes ({rsvp: rsvp})' o 'Meteor.render (function() {Template.btnYes ({rsvp: rsvp})})'. Oppure fai un pulsante di chiamata parziale che usa il brutto blocco if-else e includi sub-parziali per ogni pulsante. Includilo tramite '{{button}}' –

+0

Non ho mai pensato di fare riferimento a un modello all'interno di un helper, grazie, penso che funzionerà bene. – Sinetheta

6

Utilizzare un modello per ogni tasto e un modello di dinamica ulteriore

Il modello aiutante, restituendo il modello dinamico:

Template.nextMeetup.helpers({ 
    rsvpButtonTemplate: function(rsvp) { 
     switch(rsvp){ 
      case 'yes': return Template.buttonYes; 
      case 'maybe': return Template.buttonMaybe; 
      case 'no': return Template.buttonNo; 
      case 'none': return Template.buttonNone; 
     } 
    } 
}); 

Il modello principale, chiamando il modello aiutante:

<template name="myPage"> 
    ... 
    {{> rsvpButtonTemplate}} 
    ... 
</template> 

I tuoi 4 tasti:

<template name="buttonYes"> 
    <a {{event_url}} class="rsvp btn btn-success pull-right" title="visit event page" target="_blank"><i class="icon-check"></i> I'm Attending</a> 
</template> 
<template name="buttonMaybe"> 
    <a {{event_url}} class="rsvp btn btn-warning pull-right" title="visit event page" target="_blank"><i class="icon-warning-sign"></i> I might go</a> 
</template> 
<template name="buttonNo"> 
    <a {{event_url}} class="rsvp btn btn-danger pull-right" title="visit event page" target="_blank"><i class="icon-remove"></i> I'm not going</a> 
</template> 
<template name="buttonNone"> 
    <a {{event_url}} class="rsvp btn btn-inverse pull-right" title="visit event page" target="_blank"><i class="icon-spinner"></i> I havn't decided</a> 
</template> 
Problemi correlati