在grails中显示错误而不刷新页面

在grails中显示错误而不刷新页面,grails,groovy,Grails,Groovy,我有一个带有动态列表框的页面(从第一个列表中选择值将填充第二个列表框中的值) 列表框的验证错误工作正常,但在显示错误消息时,页面正在刷新,所选值已设置为初始状态(需要在列表框中再次选择值) 该页面设计为使用ajax调用添加任意数量的列表框,因此再次添加和选择值将是一项返工 您能帮助我显示验证错误并保持所选值不变吗(以前我遇到过类似的情况,通过用全局变量替换预处理和后处理的局部变量解决了这一问题,这次这种方法没有成功) 任何提示/帮助都很好 static constraints = {

我有一个带有动态列表框的页面(从第一个列表中选择值将填充第二个列表框中的值)

列表框的验证错误工作正常,但在显示错误消息时,页面正在刷新,所选值已设置为初始状态(需要在列表框中再次选择值)

该页面设计为使用ajax调用添加任意数量的列表框,因此再次添加和选择值将是一项返工

您能帮助我显示验证错误并保持所选值不变吗(以前我遇到过类似的情况,通过用全局变量替换预处理和后处理的局部变量解决了这一问题,这次这种方法没有成功)

任何提示/帮助都很好

static constraints = {
        deviceMapping(
                validator: {val, obj ->
                    Properties dm = (Properties) val;
                    def deviceCheck = [:];
                    if (obj.customErrorMessage == null) {
                        for (def device : dm) {
                            if (device.key == null || "null".equalsIgnoreCase(device.key)) {
                                return ["notSelected"];
                            }
                            deviceCheck.put(device.key, "");
                        }

                        if (deviceCheck.size() != obj.properties["numberOfDevices"]) {
                            return ["multipleDevicesError"];
                        }
                    }
                }
        )
        customErrorMessage (
                validator: {
                    if ("sameDeviceMultipleTimes".equals(it)) {
                        return ['sameDeviceMultipleTimes']
                    }

                }
        )
    }
    public LinkedHashMap<String, Object> preProcess(sessionObject, params, request) {
        Submission submission = (Submission) sessionObject;
        def selectedFileName = sessionObject.fileName;
        logger.debug("submission.deviceMapping :"+submission.deviceMapping)
        try {
            Customer customer = Customer.get(submission.customerId);
            OperatingSystem operatingSystem = OperatingSystem.get(submission.operatingSystemId)
            def ftpClientService = new FtpClientService();
            def files = ftpClientService.listFilesInZip(customer.ftpUser, customer.ftpPassword, customer.ftpHost, customer.ftpToPackageDirectory, selectedFileName, operatingSystem, customer.ftpCustomerTempDirectory);
            def terminalService = new TerminalService();

            OperatingSystem os = OperatingSystem.get(submission.getOperatingSystemId());
            def manufacturers = terminalService.getAllDeviceManufacturersForType(os.getType());
            logger.debug("manufacturers after os type :"+manufacturers)
            logger.debug("files in preprocess :"+files)

            def devicesForFiles = [:]
            files.each { file ->
               def devicesForThisFile = [];
               submission.deviceMapping.each { device ->
                  if (device.value == file.fileName) {
                      String manufacturer = terminalService.getManufacturerFromDevice("${device.key}");
                      def devicesForManufacturer = terminalService.getDevicesForManufacturerAndType(manufacturer, os.getType());

                     devicesForThisFile.push([device:device.key, manufacturer: manufacturer, devicesForManufacturer: devicesForManufacturer]);
                  }
               }
               devicesForFiles.put(file.fileName,devicesForThisFile);
            }
            logger.debug("devicesForFiles :"+devicesForFiles)
            return [command: this, devicesForFiles: devicesForFiles, files: files, manufacturers: manufacturers];
        } catch (Exception e) {
            logger.warn("FTP threw exception");
            logger.error("Exception", e);
            this.errors.reject("mapGameToDeviceCommand.ftp.connectionTimeOut","A temporary FTP error occurred");
            return [command: this];
        }
    }
    public LinkedHashMap<String, Object> postProcess(sessionObject, params, request) {
        Submission submission = (Submission) sessionObject;
        Properties devices = params.devices;
        Properties files = params.files;

        mapping = devices.inject( [:] ) { map, dev ->
          // Get the first part of the version (up to the first dot)
          def v = dev.key.split( /\./ )[ 0 ]
          map << [ (dev.value): files[ v ] ]

        }
        deviceMapping = new Properties();

        params.files.eachWithIndex { file, i ->
            def device = devices["${file.key}"];
            if (deviceMapping.containsKey("${device}")) {
                this.errors.reject("You cannot use the same device more than once");
                return [];
                //customErrorMessage = "sameDeviceMultipleTimes";
            }
            deviceMapping.put("${device}", "${file.value}");
        }

        if (params.devices != null) {
            this.numberOfDevices = params.devices.size(); //Used for the custom validator later on
        } else {
            this.numberOfDevices = 0;
        }
        //logger.debug("device mapping :"+deviceMapping);
        submission.deviceMapping = mapping;

        return [command: this, deviceMapping: mapping, devicesForFiles: devicesForFiles ];
    }
}
静态约束={
设备映射(
验证程序:{val,obj->
属性dm=(属性)val;
def deviceCheck=[:];
如果(obj.customErrorMessage==null){
用于(def设备:dm){
if(device.key==null | |“null”.equalsIgnoreCase(device.key)){
返回[“未选定”];
}
deviceCheck.put(device.key,“”);
}
如果(deviceCheck.size()!=对象属性[“numberOfDevices”]){
返回[“MultipleDeviceError”];
}
}
}
)
自定义错误消息(
验证器:{
如果(“sameDeviceMultipleTimes”。等于(it)){
return['sameDeviceMultipleTimes']
}
}
)
}
公共LinkedHashMap预处理(会话对象、参数、请求){
提交=(提交)sessionObject;
def selectedFileName=sessionObject.fileName;
logger.debug(“submission.deviceMapping:+submission.deviceMapping”)
试一试{
Customer=Customer.get(submission.customerId);
OperatingSystem OperatingSystem=OperatingSystem.get(submission.operatingSystemId)
def ftpClientService=新的ftpClientService();
def files=ftpClientService.listFilesInZip(customer.ftpUser、customer.ftpPassword、customer.ftpHost、customer.ftptoppackagedirectory、selectedFileName、operatingSystem、customer.ftpccustomertempdirectory);
def terminalService=新的terminalService();
OperatingSystem os=OperatingSystem.get(submission.getOperatingSystemId());
def manufacturers=terminalService.getAllDeviceManufacturersForType(os.getType());
logger.debug(“操作系统类型之后的制造商:“+制造商”)
debug(“预处理中的文件:+文件”)
def devicesForFiles=[:]
files.each{file->
def devicesForThisFile=[];
submission.deviceMapping.each{device->
if(device.value==file.fileName){
字符串制造商=terminalService.getManufacturerFromDevice(“${device.key}”);
def devicesForManufacturer=terminalService.getDevicesForManufacturerAndType(制造商,os.getType());
devicesForThisFile.push([device:device.key,制造商:manufacturer,devicesForManufacturer:devicesForManufacturer]);
}
}
devicesForFiles.put(file.fileName,devicesForThisFile);
}
debug(“DeviceForFiles:+DeviceForFiles”)
return[命令:this,devicesForFiles:devicesForFiles,files:files,manufacturers:manufacturers];
}捕获(例外e){
logger.warn(“FTP引发异常”);
错误(“异常”,e);
this.errors.reject(“mapGameToDeviceCommand.ftp.connectionTimeOut”,“发生临时ftp错误”);
return[命令:this];
}
}
公共LinkedHashMap后处理(会话对象、参数、请求){
提交=(提交)sessionObject;
属性设备=参数设备;
属性文件=params.files;
mapping=devices.inject([:]){map,dev->
//获取版本的第一部分(直到第一个点)
def v=dev.key.split(/\./)[0]
地图
def device=devices[“${file.key}”];
if(deviceMapping.containsKey(“${device}”)){
this.errors.reject(“不能多次使用同一设备”);
返回[];
//customErrorMessage=“sameDeviceMultipleTimes”;
}
deviceMapping.put(“${device}”,“${file.value}”);
}
if(params.devices!=null){
this.numberOfDevices=params.devices.size();//稍后用于自定义验证器
}否则{
此参数为.numberOfDevices=0;
}
//调试(“设备映射:+deviceMapping”);
submission.deviceMapping=映射;
return[命令:this,deviceMapping:mapping,devicesForFiles:devicesForFiles];
}
}

问题出在您的gsp页面上。确保所有字段都用值初始化

<g:text value="${objectInstance.fieldname}" ... />

此外,它选择值的方式是通过id,因此请确保也设置它:

<g:text value="${objectInstance.fieldname}" id=${device.manufacturer.id} ... />


你的问题太模糊了。您应该提供一些到目前为止您已经尝试过的示例代码。没有实际的方法来回答这个问题。用代码编辑这个问题…谢谢我有我所有的价值观。。。正如,etcg:select正在处理域类,这意味着您还应该设置id=${device.manufac