【问题标题】:Static Routes in Custom Fields in YesodYesod中自定义字段中的静态路由
【发布时间】:2013-08-22 19:43:14
【问题描述】:

我正在处理一个自定义字段,用于在 Yesod 中选择日期时间(存储为 UTCTime)。它使用Trent Richardson's timepicker。我实际上已经在工作了。唯一的问题是我在处理程序中而不是在自定义字段中拥有到 javascript 文件的静态路由。当我将它移动到自定义字段时,我得到了错误。部分代码(主要从 yesod.form.fields 复制)如下:

jqueryDateTimeField :: (RenderMessage site FormMessage, YesodJquery site) => JqueryDaySettings -> Field (HandlerT site IO) UTCTime
jqueryDateTimeField jds = Field
{
    fieldParse = parseHelper $ maybe (Left MsgInvalidDay) Right . readUTC . unpack
  , fieldView = \theId name attrs val isReq -> do
        toWidget [shamlet|
$newline never
<input id="#{theId}" name="#{name}" *{attrs} type="text" :isReq:required="" value="#{showVal val}">
|]
        addScript' urlJqueryJs
        addScript' urlJqueryUiJs
        addScript $ StaticR js_jquery_ui_timepicker_addon_js -- Bad line here
        addStylesheet' urlJqueryUiCss    --error seems to occurs on the line below
        toWidget [julius|
$(function(){
var i = document.getElementById("#{rawJS theId}");
$(i).datetimepicker({
    dateFormat:'yy-mm-dd',
    changeMonth:#{jsBool $ jdsChangeMonth jds},
    changeYear:#{jsBool $ jdsChangeYear jds},
    numberOfMonths:#{rawJS $ mos $ jdsNumberOfMonths jds},
    yearRange:#{toJSON $ jdsYearRange jds}
});
});
|]
  , fieldEnctype = UrlEncoded
}

显示addScript $ StaticR js_jquery_ui_timepicker_addon_js 的行是导致问题的原因。我知道这一点,因为当我将该行放在调用该字段的处理程序中时,它可以工作。我收到一条错误消息说

DateTime.hs:73:13:
Could not deduce (site ~ App)
from the context (RenderMessage site FormMessage, YesodJquery site)
  bound by the type signature for
             jqueryDateTimeField :: (RenderMessage site FormMessage,
                                     YesodJquery site) =>
                                    JqueryDaySettings -> Field (HandlerT site IO) UTCTime

它继续,但困扰我的是错误似乎发生在错误的行上。第 73 行是以toWidget 开头的那一行。所以,我的问题是,如何在自定义字段中使用静态路由?如果我应该提供更多信息,请告诉我。谢谢。

【问题讨论】:

    标签: haskell yesod


    【解决方案1】:

    这失败了,因为您的 jqueryDateTimeField 是通用的,即它可以与任何满足给定约束的 Yesod 站点一起使用1,但是您的 StaticR 指的是专门为您的站点,由App 数据类型(在Foundation.hs 中定义)表示。错误Could not deduce (site ~ App) 意味着在您使用StaticR 的情况下,编译器期望site 始终与App 相同,但您的其他约束不会为编译器确认它。

    对此的一种解决方案是通过将类型签名更改为:使jqueryDateTimeField 特定于您的站点:

    jqueryDateTimeField :: JqueryDaySettings -> Field Handler UTCTime
    

    请注意,HandlerHandlerT App IO 的类型同义词 — 您网站的处理程序。

    虽然这可行,但更好的解决方案是使用 YesodJqueryurlJqueryUiDateTimePicker 函数获取日期时间选择器插件的 URL 并将其添加为脚本。 urlJqueryUiDateTimePicker 接受代表您的站点的对象(在这种情况下为 App 对象)并返回 Either (Route site) Text — 您站点下的路由或基于文本的 URL — 指向 javascript 文件。您可以使用addScriptEither 将其添加为jqueryDateTimeField 中的脚本。 然后,您可以更改AppYesodJquery 实例以返回您的静态路由。

    因此,将addScript $ StaticR js_jquery_ui_timepicker_addon_js 替换为:

    app <- getYesod   -- This gets your App object
    addScriptEither (urlJqueryUiDateTimePicker app)
    

    并更改AppYesodJquery实例中的urlJqueryUiDateTimePicker方法,返回你要使用的路由:

    instance YesodJquery App where
        urlJqueryUiDateTimePicker _ = Left $ StaticR js_jquery_ui_timepicker_addon_js
    

    1 在原始类型签名中,处理程序由HandlerT site IO 表示,其中site 满足约束RenderMessage site FormMessageYesodJquery siteRenderMessage site FormMessage 要求 site 必须知道如何从 FormMessage 数据类型生成消息。 YesodJquery site 要求站点必须能够访问 jQuery、jQuery UI 和 jQuery UI 日期时间选择器插件 (see here) 的静态文件。

    【讨论】:

      猜你喜欢
      • 2019-01-05
      • 1970-01-01
      • 2017-09-20
      • 1970-01-01
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      相关资源
      最近更新 更多