Qual è la procedura migliore per il rendering di un modello GSP diverso in base al tipo di oggetto in una raccolta?

0

Diciamo che ho una collezione che è installata nel mio controller, chiamata "cose". In questa collezione c'è un assortimento eterogeneo di oggetti. Diciamo che alcuni sono di tipo "Thing" e altri sono di tipo "OtherThing". Nell'SPG pagina che rende questo elenco, voglio rendere ogni tipo di oggetto diverso in modo diverso.

So che il seguente codice funziona, ma non posso sfuggire alla sensazione che ci dovrebbe essere un modo più elegante per farlo. Qualcuno ha un modo migliore?

        <div id="eventStream">

        <ul>
            <g:each in="${things}" var="thing">

                <g:if test="${thing.type.equals( 'Thing' )}">
                    <g:render template="/renderThing" bean="thing" />
                </g:if>

                <g:if test="${thing.type.equals( 'OtherThing')}">
                    <g:render template="/renderOtherThing" bean="thing" />
                </g:if>

            </g:each>       
        </ul>

    </div>

(Nota: c'è un campo "tipo" definito su "Cosa" e "Altro" contenente quei letterali stringa. Questo è solo un collegamento).

EDIT: Mi sono appena reso conto che c'è un altro modo per farlo, che dipende dalla nozione di "convenzione sulla configurazione". Potrei semplicemente andare con una convenzione che i template hanno sempre un nome simile a:

_renderXXXXTemplate.gsp dove XXX è "Thing" o "OtherThing" o qualsiasi altra cosa. Quindi eseguo il rendering con qualcosa del tipo:

<g:render template="/render${thing.class.name}Template" bean="thing" />

Qualcuno vuole condividere i propri pensieri sul merito di questo approccio?

    
posta mindcrime 29.01.2012 - 06:05
fonte

1 risposta

1

Odio i controlli di tipo espliciti. Probabilmente inizierei con la creazione di un tag privato per il rendering di questa parte della pagina.

<myApp:renderThing object="${thing}" />

Quindi probabilmente aggiungerei un metodo astratto alla classe base per restituire il nome del modello. Certo, mescola la logica di presentazione nelle classi di business ma semplifica notevolmente la manutenzione.

abstract class Thing {
    public abstract String getTemplateName();
    ...
}

public class ThingOne extends Thing {
    public String getTemplateName() { return "templateForThingOne" }
    ...
}

Un'altra idea sarebbe quella di derivare il nome del modello dal nome della classe e aggiungere una nota nella classe base per ricordare agli sviluppatori di creare il modello appropriato per qualsiasi sottoclasse.

    
risposta data 29.01.2012 - 08:11
fonte

Leggi altre domande sui tag