Golang-Vorlagen: Die Verwendung von FuncMap mit html/template führt zu einer leeren Antwort

王林
Freigeben: 2024-02-12 11:24:07
nach vorne
1088 Leute haben es durchsucht

Golang 模板:将 FuncMap 与 html/template 结合使用会产生空响应

Bei Verwendung der Template-Engine von Golang benötigen wir häufig benutzerdefinierte Funktionen, um eine bestimmte Logik zu verarbeiten. Wenn wir jedoch eine benutzerdefinierte Funktion mit der FuncMap im Paket html/template kombinieren, kann es zu einem seltsamen Problem kommen: Es wird eine leere Antwort erzeugt. Der PHP-Editor Banana wird in diesem Artikel die Ursache dieses Problems vorstellen und Lösungen bereitstellen, um sicherzustellen, dass wir die Golang-Template-Engine korrekt verwenden können.

Frageninhalt

Mit HTML/Vorlage versuche ich, ein Datumsfeld in einem HTML-Formular mit einem Feld vom Typ template.FuncMaptime.Time auszufüllen, aber es funktioniert bei mir nicht.

Der folgende Code funktioniert,

type Task struct {
    ID          int
    ProjectID   int
    Description string
    StartDate   time.Time
    Duration    float32
}

type ProjectTaskData struct {
    ProjectID          int
    ProjectName        string
    TaskDetails        Task
    FormattedStartDate string   // this field is a hack/workaround for me
}
Nach dem Login kopieren

Meine getrimmte main Funktion,

func main() {
    db := GetConnection()

    r := mux.NewRouter()

    // other handlers here are removed

    r.HandleFunc("/project/{project-id}/add-task", AddTask(db))
    r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static/"))))

    http.ListenAndServe(":8080", r)
}
Nach dem Login kopieren

AddTask Funktion,

func AddTask(db *sql.DB) func(w http.ResponseWriter, r *http.Request) {
    //tmpl := template.Must(template.New("").Funcs(template.FuncMap{
    //  "startdate": func(t time.Time) string { return t.Format("2006-01-02") },
    //}).ParseFiles("static/add_task.html"))
    tmpl := template.Must(template.ParseFiles("static/add_task.html"))
    return func(w http.ResponseWriter, r *http.Request) {
        vars := mux.Vars(r)
        projectID, err := strconv.Atoi(vars["project-id"])
        if err != nil {
            log.Fatal(err)
        }

        var projectName string
        var projectStartDate time.Time
        err = db.QueryRow(`select name, start_date from projects where id = ?`, projectID).Scan(&projectName, &projectStartDate)
        switch {
        case err == sql.ErrNoRows:
            log.Printf("No project with id %d\n", projectID)
            return
        case err != nil:
            log.Fatalf("Query error: %v\n", err)
        default:
            log.Printf("Got project %v with id %d\n", projectName, projectID)
        }

        if r.Method != http.MethodPost {
            data := ProjectTaskData{
                ProjectID:   projectID,
                ProjectName: projectName,
                TaskDetails: Task{
                    ProjectID:   projectID,
                    Description: "",
                    StartDate:   projectStartDate,
                    Duration:    1,
                },
                FormattedStartDate: projectStartDate.Format(time.DateOnly),
            }
            tmpl.Execute(w, data)
            return
        }

        // rest of code handling the post action here
        
        http.Redirect(w, r, "/project/"+fmt.Sprint(projectID)+"/tasks", http.StatusFound)
    }
}
Nach dem Login kopieren

Wenn ich in add_task.html den folgenden Platzhalter einfüge und auf http://localhost:8080/project/1/add-task klicke, kann er das Startdatum ausfüllen,

<input type="date" id="start_date" name="start_date" value="{{.FormattedStartDate}}">
Nach dem Login kopieren

Wenn ich jedoch die folgende erste Zeile in AddTask() ersetze,

tmpl := template.Must(template.ParseFiles("static/add_task.html"))
Nach dem Login kopieren

Mit dem untenstehenden,

tmpl := template.Must(template.New("").Funcs(template.FuncMap{
        "startdate": func(t time.Time) string { return t.Format("2006-01-02") },
    }).ParseFiles("static/add_task.html"))
Nach dem Login kopieren

Wenn ich add_task.html wie folgt ändere,

<input type="date" id="start_date" name="start_date" value="{{.TaskDetails.StartDate | startdate}}">
Nach dem Login kopieren

Wenn ich http://localhost:8080/project/1/add-task drücke, erhalte ich eine leere Antwort (aber ich erhalte 200 OK)

Ich habe auch die folgende Frage ohne Erfolg erwähnt,

https://stackoverflow.com/a/35550730/8813473

Workaround

Wie @icza in den Kommentaren erwähnte, wurde das Problem durch den Erhalt der Fehlermeldung von Template.Execute() offenbart.

Ich habe eine Fehlermeldung erhalten, template: "" 是一个不完整或空的模板

Siehe die Antwort von https://www.php.cn/link/949686ecef4ee20a62d16b4a2d7ccca3, ich habe template .New("") 调用 template.New("add_task.html") geändert, um das Problem zu lösen.

Der endgültige Code lautet wie folgt:

tmpl := template.Must(template.New("add_task.html").Funcs(template.FuncMap{
        "startdate": func(t time.Time) string { return t.Format("2006-01-02") },
    }).ParseFiles("static/add_task.html"))
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonGolang-Vorlagen: Die Verwendung von FuncMap mit html/template führt zu einer leeren Antwort. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!