1

論理的な観点から、ユーザーエクスペリエンスを向上させるために、リダイレクト間で部分的なフォームデータを保持しようとしています。これにより、ユーザーは無効な部分だけをフォーム全体に再度入力する必要がなくなります。

プログラミングの観点から、request.PostForm データ構造をゴリラ セッションのフラッシュに保存しようとしています。リダイレクト後に取得できる唯一のものは、この [0xc2001c8b10] のようなメモリ アドレスの文字列表現です。

これは、検証エラーの後にフラッシュ データを保存する部分です (この前に request.ParseForm() が実行されました)。

session, _ := store.Get(request, "test")
session.AddFlash(err.Error(), "messages")
session.AddFlash(request.PostForm, "form_data")
session.Save(request, response)
http.Redirect(response, request, "/", http.StatusFound)
return

また、ゴブで構造を効果なしで登録しようとしました:

func init() {
    gob.Register(&url.Values{})
}

フォームの値は小文字です。「first_name」、「last_name」がこの動作に影響を与える可能性がある場合。

リダイレクト後に「メッセージ」を正常に取得できたことに注意してください。唯一の問題は構造データにあります。

私は何か間違ったことをしていますか、それとも私が気付いていないリダイレクト後に部分的なフォームを埋めるための別のアプローチがありますか?

4

1 に答える 1

2

あなたの問題はinterface{}、ジェネリック型であり、複数の型が存在する可能性がある場合に使用される type の値を使用していることです。これは、ゴリラのsession.Flashes() メソッドの場合です。これは、任意のユーザー データ (入力したものは何でも) を返すことができるためです。

このコードで経験していることを再現できます (再生時):

type MyData struct {
    X int
}

// Simulate Flashes() from gorilla, which returns a slice of interface{} values.
func Flashes() []interface{} {
    x := &MyData{2}

    // Convert x to type interface{}
    interfaceValue := interface{}(x)

    // Put converted x into a slice of type []interface{}
    return []interface{}{interfaceValue}
}

func main() {
    // See that [0xSOMETHING] is printed
    fmt.Println("Some data:", Flashes())
}

このプログラムを実行すると、次のような出力が表示されます。

一部のデータ: [0xc010000000]

これはあなたが経験していることと同じです。この理由はfmt.Println、ポインターとインターフェイスの抽象化のすべてのレベルをステップスルーせず、すべてを出力するように指示しない限り、特定のレベルで停止するためです。したがって、使用する場合

fmt.Printf("Some data: %#v\n", Flashes())

実際にデータが表示されます:

一部のデータ: []interface {}{(*main.MyData)(0xc010000000)}

データにアクセスするために必要なことは、結果のデータを期待するタイプに一致させることです。型アサーションを行う必要があります( play の例):

func main() {
    value := Flashes()[0]

    v, ok := value.(*MyData)

    if ok {
        fmt.Println("Some data:", v)
    } else {
        fmt.Println("Oh no, there's something else stored than expected")
    }
}

上記の例では、 によって返された最初のフラッシュFlashes()が使用され、 型であるとアサートされています*MyData。実際にこのタイプである場合、その値がコンソールに出力されます。それ以外の場合は、エラー メッセージ (適切ではありませんが) がコンソールに出力されます。あるタイプの変数をアサートした後、アサートされた値はアサートされたタイプになります。つまり、v上記の例の は type*MyTypeです。

于 2013-11-04T18:21:34.113 に答える