我正在开发一个用于在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
开头的行。所以,我的问题是,如何在自定义字段中使用静态路由?如果有更多我应该提供的信息,请告诉我。感谢。
答案 0 :(得分:3)
这会失败,因为您的jqueryDateTimeField
是通用的,即它可以与满足给定约束 1 的任何Yesod站点一起使用,但是您的StaticR
指的是路由专门为您的站点定义的构造函数,由App
数据类型(在Foundation.hs
中定义)表示。错误Could not deduce (site ~ App)
意味着在使用StaticR
的情况下,编译器期望site
始终与App
相同,但您的其他约束不会为编译器确认
此解决方案之一就是通过将类型签名更改为以下内容,使jqueryDateTimeField
特定于您的网站:
jqueryDateTimeField :: JqueryDaySettings -> Field Handler UTCTime
请注意,Handler
是HandlerT App IO
的类型同义词 - 您网站的处理程序。
虽然这样可行,但更好的解决方案是使用YesodJquery
的{{1}}函数获取日期时间选择器加载项的URL并将其添加为脚本。 urlJqueryUiDateTimePicker
接受代表您网站的对象(本例中为urlJqueryUiDateTimePicker
对象)并返回App
- 您网站下的路线或基于文字的网址 - 指向javascript文件。您可以使用addScriptEither
在Either (Route site) Text
中将其添加为脚本。
然后,您可以更改jqueryDateTimeField
的{{1}}实例以返回静态路由。
因此,请将App
替换为:
YesodJquery
并更改addScript $ StaticR js_jquery_ui_timepicker_addon_js
的{{1}}实例中的app <- getYesod -- This gets your App object
addScriptEither (urlJqueryUiDateTimePicker app)
方法,以返回您要使用的路线:
urlJqueryUiDateTimePicker
1
在原始类型签名中,处理程序由App
表示,其中YesodJquery
满足约束instance YesodJquery App where
urlJqueryUiDateTimePicker _ = Left $ StaticR js_jquery_ui_timepicker_addon_js
和HandlerT site IO
。
site
要求RenderMessage site FormMessage
必须知道如何从FormMessage
数据类型生成消息。
YesodJquery site
要求站点必须能够访问jQuery,jQuery UI和jQuery UI日期时间选择器加载项(see here)的静态文件。