簡體   English   中英

從普通字符串生成 href 值和路由模式

[英]Generating an href value and route pattern from a common string

mvc-movie-giraffe中,我在視圖中有這樣一行以生成指向編輯頁面的鏈接:

a [ _href ("/Movies/Edit/"    + (string elt.Id)) ] [ encodedText "Edit" ]

然后在我設置路線的地方,我有以下內容

routef "/Movies/Edit/%i"    edit_handler

最好分解出該字符串"/Movies/Edit/"

所以我將它和其他一些一起添加到Urls模塊中:

module Urls =

    let movies = "/Movies"
    let movies_create = "/Movies/Create"
    let movies_edit = "/Movies/Edit/%i"

對於href值:

a [ _href ("/Movies/Edit/"    + (string elt.Id)) ] [ encodedText "Edit" ]

我們可以這樣做:

a [ _href (sprintf (Printf.StringFormat<int->string>(Urls.movies_edit)) elt.Id) ] [ encodedText "Edit" ]

對於路線案例:

routef "/Movies/Edit/%i"    edit_handler

我們做得到:

routef (PrintfFormat<obj, obj, obj, obj, int>(Urls.movies_edit))    edit_handler

這似乎確實有效!

我的問題是,有沒有更好的方法? 也許更簡潔的東西? 上面的語法有點重。 或者是否已經有一些既定的最佳實踐?

我查看了Giraffe 樣本,並沒有注意到使用了這種技術。

更新 - 方法 #2

這是一種方法。 基本上,還要排除那些較長的表達式:

module Urls =

    let movies = "/Movies"
    let movies_create = "/Movies/Create"

    let movies_edit = "/Movies/Edit/%i"
    let movies_edit_href = sprintf (Printf.StringFormat<int->string>(movies_edit))
    let movies_edit_route = PrintfFormat<obj, obj, obj, obj, int>(movies_edit)

然后在視圖中引用它們:

a [ _href (Urls.movies_edit_href elt.Id) ] [ encodedText "Edit" ]

以及設置路線時:

routef Urls.movies_edit_route edit_handler

更新 - 方法#3

使用方法 #2,我得到了這個:

module Urls =

    let movies = "/Movies"

    let movies_create = "/Movies/Create"
    
    let movies_edit = "/Movies/Edit/%i"
    let movies_edit_href = sprintf (Printf.StringFormat<int->string>(movies_edit))
    let movies_edit_route = PrintfFormat<obj, obj, obj, obj, int>(movies_edit)

    let movies_details = "/Movies/Details/%i"
    let movies_details_href = sprintf (Printf.StringFormat<int->string>(movies_details))
    let movies_details_route = PrintfFormat<obj, obj, obj, obj, int>   (movies_details)

    let movies_delete = "/Movies/Details/%i"
    let movies_delete_href = sprintf (Printf.StringFormat<int->string>(movies_delete))
    let movies_delete_route = PrintfFormat<obj, obj, obj, obj, int>   (movies_delete)

那里有一些重復,所以我定義了這些擴展:

type String with
    member this.route = PrintfFormat<obj, obj, obj, obj, int>(this)
    member this.href = sprintf (Printf.StringFormat<int->string>(this))

現在, Urls模塊只是:

module Urls =

    let movies         = "/Movies"
    let movies_create  = "/Movies/Create"
    let movies_edit    = "/Movies/Edit/%i"
    let movies_details = "/Movies/Details/%i"
    let movies_delete  = "/Movies/Details/%i"

然后獲取movies_edithref字符串:

a [ _href (Urls.movies_edit.href elt.Id) ] [ encodedText "Edit" ]

與路線類似:

routef Urls.movies_edit.route edit_handler

我肯定在工作中這樣做是為了分享 url 路由模板。

type Route<'t> = PrintfFormat<obj, obj, obj, obj, 't>
let Details = Route<Guid> ("/Details/%O")

然后在我的路由處理程序和我的視圖中引用它來生成路由。 不過有幾點需要注意:

  • 對於值(如 let 綁定),您不能將PrintfFormat類型的通用參數保留為“打開”。 所以他們統一到obj ,這就是你所看到的。

  • 如果出於某種原因需要保持通用參數打開,解決方法是將該值轉換為帶有單元參數的inline function,然后在每個調用點調用該 function:

let inline Details () = PrintfFormat<_,_,_,_,Guid> "/Details/%O"

這超越了許多 ML 系列語言所具有的“價值限制”。 您可以查找該術語以了解為什么通用參數必須在值綁定上保持開放。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM