Blimey, еще одно гнездо червей ...
Во-первых, <input type="date"
или <input type="datetime-local"
в интерпретации chrome отображает значение браузера как 'mm / dd / yyyy' для даты и для datetime-локальный как мм / дд / гггг ЧЧ: мм: (сс: SSS - выделен серым цветом)
Когда вы предоставляете value="string"
, он игнорирует вашу строку - поэтому вы должны передать фактический значение на входе как значение = "$ {значение}".Если вы преобразуете это в форматированное поле раньше, то оно игнорируется, и отображается шаблон по умолчанию.
Следующая проблема - при отправке формы значение, отправленное в ваш блок params, фактически является строкой в формате ISO, а неa LocalDateTime и т. д.
Поэтому, когда Grails пытается загрузить для вас запись из базы данных и вставить ее в ваш контроллер, он уже пытался обновить запись один раз.
Проблема в том, что этопроизвел проверку, которая уже не удалась.Поэтому, когда вы получаете объект домена в вашем методе «Update (Domain xxx) {...}», объект уже имеет свои ошибки.
Поэтому я попытался преобразовать строки, отправленные в параметрах, в LocalDateTime, LocalDate, а затем обновить мой объект домена в контроллере - но они потерпели неудачу при использовании validate () в качестве ранее существовавших ошибок там, где они уже есть.
Поэтому мне пришлось сначала удалить ошибки, а затем преобразовать строки параметров вправоТипы дат Java, а затем обновить объект домена и затем проверить.Тогда это радует.
Таким образом, действие контроллера теперь должно выглядеть следующим образом
def update(BootstrapTest bootstrapTest) {
if (bootstrapTest == null) {
notFound()
return
}
LocalDateTime ldtProp
LocalDate dtProp
if (bootstrapTest.hasErrors()) {
bootstrapTest.clearErrors()
try {
ldtProp = LocalDateTime.parse(params.ldtProp?.toString()) //ISO_LOCAL_DATE_TIME
dtProp = LocalDate.parse(params.dtProp?.toString(), DateTimeFormatter.ISO_LOCAL_DATE) //ISO_LOCAL_DATE
bootstrapTest.ldtProp = ldtProp
bootstrapTest.dtProp = dtProp
bootstrapTest.validate()
} catch (ex) {
println "exception $ex.message"
respond bootstrapTest.errors, view:'edit'
return
}
}
try {
bootstrapTestService.save(bootstrapTest)
} catch (ValidationException e) {
respond bootstrapTest.errors, view:'edit'
return
} ...
Итак, сначала очистите ошибки - затем исправьте / преобразуйте формат карты параметров в формат объекта домена, и это нормально.для свойства класса домена (или определить метод set в домене, который принимает строку и выполняет преобразование внутри)
Как только вы это сделаете, на этот раз повторная проверка завершится успешно, и обновления контроллера / БД начнут работать.
Без использования пользовательских средств выбора даты и т. Д. (И для лесов, которые являются излишними) вам придется жить с текущей обработкой данных для
Я не пробовал это в другом браузере, но Chrome - мой «обычный» браузер разработчика и ведет себякак указано выше.
- PS - дополнительная трассировка.В фоновом режиме, когда объект Domain расположен и загружен, Grails, кажется, имеет преобразователь из String в DateTime, потому что я создал setDtProp (dt) setter - и это вызывается с преобразованным значением, прежде чем объект будет доставлен в контроллер - которыйВот почему я увидел первоначально описанное изменение dtProp, но не изменило ldtProp (где я добавил сеттер также в доменном объекте).
Таким образом, как бы Grails ни выполнял процесс внедрения, он не делает это для LocalDateTime как строки из браузера (но он помещает строку в параметры для вас), но он вызывает метод установки для LocalDate.В любом случае, когда объект домена загружен, его ошибки () были установлены - поэтому вам нужно обработать это с контроллера, как показано.Попытка исправить с помощью сеттеров в классе Domain не работает для LocalDateTime, так как ваш сеттер никогда не вызывается!
Это может быть обработано в контроллере только после того, как объект введен, как показано выше, как я начал делать в первую очередь.