Templat Golang: Menggunakan FuncMap dengan html/template menghasilkan respons kosong

王林
Lepaskan: 2024-02-12 11:24:07
ke hadapan
1088 orang telah melayarinya

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

Apabila menggunakan enjin templat Golang, kami sering memerlukan fungsi tersuai untuk mengendalikan beberapa logik tertentu. Walau bagaimanapun, apabila kami menggabungkan fungsi tersuai dengan FuncMap dalam pakej html/template, kami mungkin menghadapi masalah pelik: respons kosong dihasilkan. Editor PHP Banana akan memperkenalkan punca masalah ini dalam artikel ini dan menyediakan penyelesaian untuk memastikan kami boleh menggunakan enjin templat Golang dengan betul.

Kandungan soalan

Menggunakan html/templat Saya cuba mengisi medan tarikh dalam bentuk HTML menggunakan medan jenis template.FuncMaptime.Time tetapi ia tidak berfungsi untuk saya.

Kod berikut berfungsi,

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
}
Salin selepas log masuk

Fungsi main saya yang dipangkas,

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)
}
Salin selepas log masuk

AddTask fungsi,

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)
    }
}
Salin selepas log masuk

Dalam add_task.html, jika saya meletakkan pemegang tempat berikut, apabila saya mengklik pada http://localhost:8080/project/1/add-task, ia dapat mengisi tarikh mula,

<input type="date" id="start_date" name="start_date" value="{{.FormattedStartDate}}">
Salin selepas log masuk

Walau bagaimanapun, jika saya menggantikan baris pertama berikut dalam AddTask(),

tmpl := template.Must(template.ParseFiles("static/add_task.html"))
Salin selepas log masuk

Dengan yang di bawah,

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"))
Salin selepas log masuk

Jika saya menukar add_task.html seperti berikut,

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

Apabila saya menekan http://localhost:8080/project/1/add-task saya mendapat respons kosong (tetapi saya mendapat 200 OK)

Saya juga menyebut soalan berikut tanpa berjaya,

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

Penyelesaian

Seperti yang @icza sebutkan dalam ulasan, menerima ralat daripada Template.Execute() mendedahkan isu itu.

Saya mendapat ralat, template: "" 是一个不完整或空的模板

Rujuk jawapan https://www.php.cn/link/949686ecef4ee20a62d16b4a2d7ccca3, saya tukar template .New("") 调用 template.New("add_task.html") untuk menyelesaikan masalah.

Kod akhir adalah seperti berikut,

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"))
Salin selepas log masuk

Atas ialah kandungan terperinci Templat Golang: Menggunakan FuncMap dengan html/template menghasilkan respons kosong. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!