Itérer sur la carte dans le modèle

91

J'essaye d'afficher une liste de cours de gym (Yoga, Pilates, etc.). Pour chaque type de cours, il y a plusieurs cours, je souhaite donc regrouper tous les cours de yoga, et tous les cours de Pilates, etc.

J'ai fait cette fonction pour prendre une tranche et en faire une carte

func groupClasses(classes []entities.Class) map[string][]entities.Class {
    classMap := make(map[string][]entities.Class)
    for _, class := range classes {
        classMap[class.ClassType.Name] = append(classMap[class.ClassType.Name], class)
    }
    return classMap
}

Le problème est maintenant de savoir comment puis-je le parcourir, selon http://golang.org/pkg/text/template/ , vous devez y accéder au .Keyformat, je ne connais pas les clés (sauf si j'ai également passé une tranche de clés dans le modèle). Comment décompresser cette carte à mon avis.

Tout ce que j'ai actuellement est

{{ . }} 

qui affiche quelque chose comme:

map[Pilates:[{102 PILATES ~/mobifit/video/ocen.mpg 169 40 2014-05-03 23:12:12 +0000 UTC 2014-05-03 23:12:12 +0000 UTC 1899-12-30 00:00:00 +0000 UTC {PILATES Pilates 1 2014-01-22 21:46:16 +0000 UTC} {1 leebrooks0@gmail.com password SUPERADMIN Lee Brooks {Male true} {1990-07-11 00:00:00 +0000 UTC true} {1.85 true} {88 true} 2014-01-22 21:46:16 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false} {0001-01-01 00:00:00 +0000 UTC false} {0001-01-01 00:00:00 +0000 UTC false}} [{1 Mat 2014-01-22 21:46:16 +0000 UTC}]} {70 PILATES ~/mobifit/video/ocen.mpg 119 66 2014-03-31 15:12:12 +0000 UTC 2014-03-31 15:12:12 +0000 UTC 1899-12-30 00:00:00 +0000 UTC 
Lee
la source

Réponses:

167

Consultez la section Variables dans la documentation du modèle Go. Une plage peut déclarer deux variables, séparées par une virgule. Les éléments suivants devraient fonctionner:

{{ range $key, $value := . }}
   <li><strong>{{ $key }}</strong>: {{ $value }}</li>
{{ end }}
Herman Schaaf
la source
46

Comme Herman l'a souligné, vous pouvez obtenir l'index et l'élément de chaque itération.

{{range $index, $element := .}}{{$index}}
{{range $element}}{{.Value}}
{{end}}
{{end}}

Exemple de travail:

package main

import (
    "html/template"
    "os"
)

type EntetiesClass struct {
    Name string
    Value int32
}

// In the template, we use rangeStruct to turn our struct values
// into a slice we can iterate over
var htmlTemplate = `{{range $index, $element := .}}{{$index}}
{{range $element}}{{.Value}}
{{end}}
{{end}}`

func main() {
    data := map[string][]EntetiesClass{
        "Yoga": {{"Yoga", 15}, {"Yoga", 51}},
        "Pilates": {{"Pilates", 3}, {"Pilates", 6}, {"Pilates", 9}},
    }

    t := template.New("t")
    t, err := t.Parse(htmlTemplate)
    if err != nil {
        panic(err)
    }

    err = t.Execute(os.Stdout, data)
    if err != nil {
        panic(err)
    }

}

Production:

Pilates
3
6
9

Yoga
15
51

Aire de jeu: http://play.golang.org/p/4ISxcFKG7v

ANisus
la source
Hé @ANisus, j'ai besoin de générer json via un modèle comme ci-dessous mais il a aussi des virgules supplémentaires comme dans le tableau d'adresses dans l'exemple donné Sortie `` `{" name ":" Mus "," adresses ": [{" address ":" A "}, {" address ":" B "},]}` `` `Exemple de lien de code play.golang.org/p/nD08y0noPHv
Mohammad Mustaqeem
1
@MohammadMustaqeem Vous pouvez vérifier l'index de chaque itération, et ne pas ajouter de virgule à la première itération. Voir exemple: play.golang.org/p/5544hc_0_g8 . Fais attention. Le rendu JSON avec des modèles entraînera des problèmes d'échappement. Voir l'adresse "C&D" que j'ai ajoutée.
ANisus
Merci. J'ai résolu le problème de fuite en important "texte / modèle" au lieu de "html / modèle". play.golang.org/p/PXTNZGWx7Yi
Mohammad Mustaqeem
1
@MohammadMustaqeem Malheureusement, vous pouvez maintenant obtenir un JSON invalide, ou pire encore, un JSON injecté: play.golang.org/p/kd9bM_rpwyg . L'utilisation d'un modèle pour générer json n'est pas judicieuse, mais si vous devez le faire, échappez aux valeurs JSON avec des fonctions telles que js (également dans cet exemple).
ANisus