Go 的web页面动态加载实现。
1. 在MySQL中添加表项 users,构造多条数据。
CREATE TABLE IF NOT EXISTS users( id INT UNSIGNED AUTO_INCREMENT, username VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, create_at INT(10) UNSIGNED NOT NULL, PRIMARY KEY (id) )ENGINE=INNODB DEFAULT CHARSET=UTF8;
main.go 如下
package main import ( "bytes" _ "crypto/tls" "database/sql" "encoding/json" "fmt" _ "github.com/go-sql-driver/mysql" "github.com/gorilla/mux" "html/template" "log" "net/http" "strconv" "time" ) const ( DB_ADDR_PORT = "localhost:3307" DB_LOGIN_USER = "root" DB_LOGIN_PASS = "usbw" DB_TAB = "test" PAGE_SIZE = 2 ) var DBObj *sql.DB type UserList struct { UsersList []User Ajax bool Total int Index int PageSize int } type User struct { Id int Username string Password string CreateAt uint } func dbInit() { dsn := fmt.Sprintf("%s:%s@(%s)/%s", DB_LOGIN_USER, DB_LOGIN_PASS, DB_ADDR_PORT, DB_TAB) db, err := sql.Open("mysql", dsn) if err != nil { log.Fatalf("connect db failed %v", err) return } if err := db.Ping(); err != nil { log.Fatalf("ping db failed %v", err) return } DBObj = db //fmt.Printf("db reachable, %T\n", db) } func dbFetch(id int) (*User, bool) { user := new(User) query := `SELECT id, username, password, create_at FROM users WHERE id=?` err := DBObj.QueryRow(query, id).Scan(&user.Id, &user.Username, &user.Password, &user.CreateAt) if err != nil { return &User{}, false } return user, true } func dbFetchallPerpage(index int) (*UserList, int, bool) { total := 0 query := `SELECT COUNT(*) FROM users WHERE 1=1` err := DBObj.QueryRow(query).Scan(&total) if err != nil { return &UserList{}, total, false } if total == 0 { return &UserList{}, total, false } query = `SELECT id, username, password, create_at FROM users WHERE id < ? LIMIT ?, ?` rows, err := DBObj.Query(query, 20, (index-1)*PAGE_SIZE, PAGE_SIZE) if err != nil { return &UserList{}, total, false } defer rows.Close() var userlist UserList for rows.Next() { u := User{} err := rows.Scan(&u.Id, &u.Username, &u.Password, &u.CreateAt) if err != nil { continue } userlist.UsersList = append(userlist.UsersList, u) } err = rows.Err() if err != nil { return &UserList{}, total, false } return &userlist, total, true } func (user *User) Print(s string) string { timeObj := time.Unix(int64(user.CreateAt), 10) var buffer bytes.Buffer buffer.WriteString(s) buffer.WriteString(strconv.Itoa(user.Id)) buffer.WriteString(" ") buffer.WriteString(timeObj.Format("2006-01-02 15:04:05")) //fmt.Printf("<%s>\n", buffer.String()) return buffer.String() } func GetUserById(idStr string) string { id, _ := strconv.Atoi(idStr) respFields := make(map[string]string) respFields["rv"] = "0" fmt.Println("after fetch ", idStr) if user, rv := dbFetch(id); rv { respFields["rv"] = "1" respFields["username"] = user.Username respFields["id"] = strconv.Itoa(user.Id) } jsonResp, _ := json.Marshal(respFields) return string(jsonResp) } func AllUserScroll(w http.ResponseWriter, r *http.Request) { fmt.Println("AllUsersScroll") r.ParseForm() page, _ := strconv.Atoi(r.FormValue("page")) ajax := (r.FormValue("ajax") == "1") //fmt.Printf("r %v %v\n", page, ajax) page = func(p int) int { if p > 1 { return p } return 1 }(page) t := template.Must(template.ParseFiles("templates/scroll_load.html")) fmt.Println("after fetch") if Users, total, rv := dbFetchallPerpage(page); rv { Users.Ajax = ajax Users.Total = total Users.PageSize = PAGE_SIZE Users.Index = page t.Execute(w, Users) return } t.Execute(w, []byte("failed to get user")) } func EditUser(w http.ResponseWriter, r *http.Request) { fmt.Println("in edit") err := r.ParseForm() if err != nil { fmt.Println(err.Error) } vars := mux.Vars(r) id := vars["idStr"] name := r.FormValue("name") fmt.Println(name, id) res, err := DBObj.Exec("UPDATE users SET username=? WHERE id=?", name, id) fmt.Println(res) if err != nil { fmt.Println(err.Error) } respFields := make(map[string]string) respFields["rv"] = "1" respFields["msg"] = "success" jsonResp, _ := json.Marshal(respFields) w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, "%s", string(jsonResp)) } func GetUser(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) idStr := vars["idStr"] t := template.Must(template.ParseFiles("templates/detail.html")) id, _ := strconv.Atoi(idStr) fmt.Println("after fetch") if user, rv := dbFetch(id); rv { t.Execute(w, user) return } t.Execute(w, []byte("failed to get user")) } func RedireIndex(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/users", 301) } func APIUser(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) idStr := vars["idStr"] id, err := strconv.Atoi(idStr) if err != nil { http.Error(w, http.StatusText(404), http.StatusNotFound) return } fmt.Println("after fetch") if user, rv := dbFetch(id); rv { APIOutput, err := json.Marshal(user) fmt.Println(string(APIOutput)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, string(APIOutput)) return } http.Error(w, http.StatusText(401), http.StatusForbidden) } func main() { dbInit() r := mux.NewRouter() r.HandleFunc("/", RedireIndex) userrouter := r.PathPrefix("/users").Subrouter() userrouter.HandleFunc("", AllUserScroll).Methods("GET") userrouter.HandleFunc("/{idStr:[0-9]+}", GetUser).Methods("GET") apirouter := r.PathPrefix("/api").Subrouter() apirouter.HandleFunc("/{idStr:[0-9]+}", APIUser).Methods("GET") apirouter.HandleFunc("/editUser/{idStr:[0-9]+}", EditUser).Methods("POST") http.ListenAndServe(":8080", r) }
2. 页面 scroll_load.html 内容如下:
{{if not .Ajax}} <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="format-detection" content="telephone=no, address=no"> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-touch-fullscreen" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title>scrollable loading</title> <style> html, body { margin: 0px 3px; } html { background: #EDF0F3; height: 100%; } /* 浏览更多 */ .show-more { text-align: center; margin: 10px 0 65px 0px; } .show-more a { display: inline-block; color: #008000; font-size: 13px; text-shadow: 0 1px 1px #fff; box-shadow: 0 1px 1px 0 rgba(0,0,0,0.2) inset; padding: 8px 50px; background: #ebebeb; text-decoration: none; border-radius: 5px; } </style> </head> <body> <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"> </script> <h1>User list</h1> <div id="list"> {{end}} {{range $k, $v := .UsersList}} <div> <div>{{$k}} => {{$v}}</div> <div>{{.Print "--->"}}</div> <div class="edit"> <form onsubmit="return edit(this, {{.Id}})"> <input type="text" class="name_{{.Id}}" name="name" value="{{.Username}}" /> <input type="submit" value="Edit"/> </form> </div> </div> {{end}} {{if not .Ajax}} </div> <div id="result"></div> {{if gt .Total .PageSize}} <div style="margin: 40px 0px; text-align: center;"> <div class="show-more"><a href="javascript:void(0);" style="color: #000;" onclick="loadPage('{{.Index}}', 'list')" class="img-rounded" id="pager">浏览更多</a> </div> </div> {{end}} </body> <script type="text/javascript"> var all_done = false function edit(that, id){ var name = $(".name_" + id).val() var url = '/api/editUser/' + id var param = {} param.name = name $.post(url, param, function(res){ if (res.rv == '1'){ $('#result').html('success') } else { console.log(res) } }, "json") return false; } function loadPage(pindex, container) { if (all_done){ return; } pindex = parseInt(pindex) + 1; $('#pager').html('加载中...'); $.get(location.href, {'page' : pindex, 'ajax' : "1"}, function(html){ if (html.indexOf('name_') > -1) { $('#'+container).append(html); $('#pager').get(0).onclick = function(){ loadPage(pindex, container); } $('#pager').html("浏览更多"); } else { all_done = true; $('#pager').html('已经显示全部'); } }); } </script> </html> {{end}}
3. 显示如下,在点击 “浏览更多” 之后,List 动态添加载到页面。
标签:web,http,err,fmt,golang,user,return,id,加载 From: https://www.cnblogs.com/wallywl/p/17393771.html