更新:我已将此错误隔离在此select中注册onchange事件。如果我删除onchange,页面呈现没有错误,否则我得到 No javascript provider 错误。
<g:select optionKey="id" optionValue="name" name="course" id="course"
from="${com.TourneyCard.Course.list(sort:'name')}" value="${homeCourse.id}"
onchange="${remoteFunction(controller:'foursome', action:'ajaxGetTeesJSON',
params:'\'id=\' + escape(this.value)',
onSuccess:'updateTees(data);')}">
</g:select>
由于各种原因,我想使用资源插件而不是jQuery插件来包含jQuery。它主要工作,但我有一个页面无法呈现,而是发出错误没有配置javascript提供程序。
我的ApplicationResources.groovy定义了jquery:
jquery {
resource url: 'js/jquery/jquery-1.9.1.min.js', disposition: 'head'
}
我的main.gsp布局如下所示:
<head>
<g:layoutHead/>
<g:javascript library="jquery"/>
<r:require module="jquerymobile"/>
<r:layoutResources />
</head>
发出提供程序未配置错误的页面如下所示:
<head>
<meta content="main" name="layout">
<r:require modules="jqmdatebox,jqmgrid960,updateTees"/>
....
</head>
<body>
....
<g:javascript>
var zselect = document.getElementById('tee')
var zopt = zselect.options[zselect.selectedIndex]
</g:javascript>
</body>
答案 0 :(得分:2)
由于您手动设置JQuery资源,因此无需设置:
<g:javascript library="jquery"/>
相反,只需要你的模块:
<r:requires module="jquery, jquerymobile"/>
修改强>
查看您的新信息,我认为您的问题是使用remoteFunction
方法。因为它需要知道你正在使用哪个javascript库。尝试将<g:setProvider library="jquery"/>
添加到您的网页。
答案 1 :(得分:1)
我刚刚解决了由 g:remoteLink 标记引起的同一错误。我发现我需要两次调用 。一旦进入头部,另一个在页脚中,你应该从中加载js文件。我还必须在BuildConfig.groovy
中添加jQuery作为插件plugins {
runtime ":jquery:1.8.3"
runtime ':resources:1.2'
...
}
我的main.gsp有
<r:require modules="app, jquery" />
<g:setProvider library="jquery" />
<r:layoutResources/>
<g:layoutHead />
我有g:layoutHead,所以jQuery在可能需要它的脚本之前加载。
如果您只是内联某些脚本,可能需要查看
如果您使用此标记呈现内联JavaScript代码,建议您使用Resources插件的标记来生成包含在正文末尾的内联脚本,或者在必要时生成内部脚本 - 而不是排队。要获得更多控制,请直接使用Resources插件的标记。 -
答案 2 :(得分:0)
尝试放
grails.views.javascript.library = "jquery"
进入Config.groovy或插入主布局:
<g:setProvider library="jquery"/>
答案 3 :(得分:0)
此解决方案对我有用:
将以下类(来自jquery Grails插件)添加到您的应用程序中
import org.codehaus.groovy.grails.plugins.web.taglib.JavascriptProvider
class JQueryProvider implements JavascriptProvider {
/**
* doRemoteFunction creates a jQuery-AJAX-Call
*
* @param taglib
* @param attrs
* @param out
*
* @return the jQuery-like formatted code for an AJAX-request
*/
def doRemoteFunction(taglib, attrs, out) {
// Optional, onLoad
if (attrs.onLoading) {
out << "${attrs.onLoading};"
}
// Start ajax
out << /jQuery.ajax({/
// Method
def method = (attrs.method ? attrs.remove('method') : 'POST')
out << "type:'$method'"
// Optional, synchron call
if ("false" == attrs.asynchronous) {
out << ",async:false"
attrs.remove('asynchronous')
}
// Optional, dataType to use
if (attrs.dataType) {
out << ",dataType:'${attrs.remove('dataType')}'"
}
// Additional attributes
if (attrs.params || attrs.jsParams) {
if (!(attrs?.params instanceof Map)) {
// tags like remoteField don't deliver a map
out << ",data:${attrs.remove('params')}"
} else {
out << ",data:{"
boolean hasParams = false
if (attrs?.params instanceof Map) {
hasParams = true
out << attrs.remove('params').collect { k, v ->
"\'" +
"${k}".encodeAsJavaScript() +
"\': \'" +
"${v}".encodeAsJavaScript() +
"\'"
}.join(",")
}
if (attrs?.jsParams instanceof Map) {
if (hasParams) {
out << ","
}
out << attrs.remove('jsParams').collect { k, v ->
"\'" +
"${k}".encodeAsJavaScript() +
"\': \'" +
"${v}".encodeAsJavaScript() +
"\'"
}.join(",")
}
out << "}"
}
}
// build url
def url = attrs.url ? taglib.createLink(attrs.remove('url')) : taglib.createLink(attrs);
out << ", url:'${url}'"
// Add callback
buildCallback(attrs, out)
// find all onX callback events
def callbacks = attrs.findAll { k, v ->
k ==~ /on(\p{Upper}|\d){1}\w+/
}
// remove all onX callback events
callbacks.each { k, v ->
attrs.remove(k)
}
out << "});"
// Yeah, I know, return is not needed, but I like it
return out
}
/**
* Helper method to create callback object
*
* @param attrs Attributes to use for the callback
* @param out Variable to attache the output
*/
def buildCallback(attrs, out) {
// TODO check for strlen
if (out) {
out << ','
}
//*** success
out << 'success:function(data,textStatus){'
if (attrs.onLoaded) {
out << "${attrs.onLoaded};"
}
if (attrs.update instanceof Map) {
if (attrs.update?.success) {
out << "jQuery('#${attrs.update.success}').html(data);"
}
} else if (attrs.update) {
out << "jQuery('#${attrs.update}').html(data);"
}
if (attrs.onSuccess) {
out << "${attrs.onSuccess};"
}
out << '}'
//*** failure
out << ',error:function(XMLHttpRequest,textStatus,errorThrown){'
if (attrs.update instanceof Map) {
if (attrs.update?.failure) {
// Applied to GRAILSPLUGINS-1919
out << "jQuery('#${attrs.update?.failure}').html(XMLHttpRequest.responseText);"
}
}
if (attrs.onFailure) {
out << "${attrs.onFailure};"
}
out << '}'
if (attrs.onComplete) {
out << ",complete:function(XMLHttpRequest,textStatus){${attrs.onComplete}}"
}
}
/**
* Serializes the surrounding form.
*
* @param attrs attrs.params to serialize
*/
def prepareAjaxForm(attrs) {
// Fix for http://jira.codehaus.org/browse/GRAILSPLUGINS-1865
if (attrs.forSubmitTag) {
attrs.params = "jQuery(this).parents('form:first').serialize()".toString()
}
else {
attrs.params = "jQuery(this).serialize()".toString()
}
}
}
在Bootstrap.groovy
import org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib
class BootStrap {
def init = { servletContext ->
JavascriptTagLib.PROVIDER_MAPPINGS.jquery = JQueryProvider
}
}
答案 4 :(得分:-1)
此链接非常有用,它显示了您可能需要采取的步骤。 https://grails.org/plugin/jquery
编辑: 在上面的网站上,我这样做是很烦的: