Heim  >  Artikel  >  Backend-Entwicklung  >  Golang-Vorlagen: Die Verwendung von FuncMap mit html/template führt zu einer leeren Antwort

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

王林
王林nach vorne
2024-02-12 11:24:071087Durchsuche

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
}

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)
}

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)
    }
}

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}}">

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

tmpl := template.Must(template.ParseFiles("static/add_task.html"))

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"))

Wenn ich add_task.html wie folgt ändere,

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

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"))

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen