grails - 不刷新的 save() 不保存记录?
问题描述
我正在玩 grails 3 应用程序。我用粗鲁的动作创建了这个简单的图书应用程序。它没有更新记录。
这里是书域
package bookapp
class Book {
String name
static constraints = {
}
}
这是图书控制器
package bookapp
import grails.plugin.springsecurity.annotation.Secured
@Secured('ROLE_USER')
class BookController {
def index() {
[books: Book.findAll()]
}
def create(){
}
def save(){
def book = new Book(params)
book.save()
redirect(action:'show', id:book.id)
}
def edit(Long id){
[book: Book.get(id)]
}
def update(Long id){
def book = Book.get(id)
bindData(book, params)
book.save()
redirect(action:'show', id:book.id)
}
def show(Long id){
[book: Book.get(id)]
}
def destroy(){
}
}
这是编辑视图页面
<h1> Edit Book Page</h1>
<g:form action="update" id="${book.id}">
<g:textField name="name" value="${book.name}"></g:textField>
<g:submitButton name="submit"></g:submitButton>
</g:form>
当我在编辑页面并更改名称字段时,然后单击提交按钮。它不会更新这本书。如果我将更新操作更改为
def update(Long id){
def book = Book.get(id)
bindData(book, params)
book.save(flush:true)
redirect(action:'show', id:book.id)
}
这行得通。所以我的问题是为什么我们需要显式刷新?为什么 save() 不保存记录?我错过了什么吗?感谢帮助!
完整代码:
首先创建一个域Book如下
class Book {
String name
static constraints = {
}
}
创建图书控制器
class BookController {
def index() {
[books: Book.findAll()]
}
def create(){
}
def save(){
def book = new Book(params)
book.save()
redirect(action:'show', id:book.id)
}
def edit(Long id){
[book: Book.get(id)]
}
def update(Long id){
def book = Book.get(id)
book.properties = params
book.save()
redirect(action:'show', id:book.id)
}
def show(Long id){
[book: Book.get(id)]
}
def destroy(Long id){
Book.get(id).delete()
redirect(action:'index')
}
}
意见
创建.gsp
<h1> Create Book Page</h1>
<g:form action="save">
<g:textField name="name"></g:textField>
<g:submitButton name="submit"></g:submitButton>
</g:form>
编辑.gsp
<h1> Edit Book Page</h1>
<g:form action="update" id="${book.id}">
<g:textField name="name" value="${book.name}"></g:textField>
<g:submitButton name="submit"></g:submitButton>
</g:form>
索引.gsp
<g:each in="${books}" var="book">
<h2><g:link action="show" id="${book.id}"> ${book.name} </g:link></h2>
</g:each>
<g:link controller="book" action="create">Create Book</g:link>
显示.gsp
<h1> ${book.name} </h1>
<g:link action="edit" id="${book.id}">Edit</g:link>
<g:link action="destroy" id="${book.id}">Delete</g:link>
<g:link action="index">Back</g:link>
删除和更新不适用于 save()。需要添加保存(刷新:真)。谢谢!
更新: 这很奇怪。相同的代码适用于 grails 2。我尝试使用 grails 2.2。它只是不适用于 grails 3。我用来测试的 grails 3 版本是 grails 3.3.6。grails 3中是否有任何改变打破了这一点?
更新 2:
我现在已将删除操作移至服务,如下所示。
@Transactional
class BookService {
def destroy(Long id) {
def b = Book.get(id)
b.delete()
}
}
在控制器中
class BookController {
def bookService
def destroy(Long id){
bookService.destroy(id)
redirect(action:'index')
}
}
要删除的查看代码是
<h1> ${book.name} </h1>
<g:link action="edit" id="${book.id}">Edit</g:link>
<g:link action="destroy" id="${book.id}">Delete</g:link>
<g:link action="index">Back</g:link>
当我单击删除时,它会重定向到索引页面,但我仍然可以看到记录。我错过了什么吗?谢谢!
解决方案
我在我曾经开发过的每个 Grails 应用程序中都看到了两个经典错误。所以不要气馁。
首先,虽然您可以在控制器中进行持久性,但您不应该将服务与您的业务逻辑与路由和渲染分离。
其次,当您进行数据库修改时,您应该使用事务。在 Grails 中,您可以使用 @Transactional 来做到这一点,您可以将其添加到方法或类中。一般来说,您不必执行flush:true,除非您需要已保存记录的ID。@Transactional 可以接受许多参数来改变事务的工作方式: https ://docs.grails.org/latest/guide/services.html#declarativeTransactions
不久前,我为 Grails 3 创建了这些架构图: https ://github.com/virtualdogbert/Grails_Architecture
我还创建了这个页面作为 Groovy/Grails 资源的地方: https ://github.com/virtualdogbert/Groovy_Links
希望有帮助。
对于删除是您在服务中的列表设置,如下所示:
class BookService {
@Transactional(readOnly = true)
def listBooks() {
Book.list()
}
推荐阅读
- jquery - 如何在 react.js 中更改滚动导航栏的背景和文本颜色?
- java - 如何将 FieldValue.serverTimestamp() 转换为 Kotlin/Java 日期类
- highcharts - HighCharts 图表问题
- javascript - 防止重复函数onchange事件jQuery
- docker - npm 错误!在为 Node 项目创建 Docker 映像时,跟踪器“idealTree”已经存在
- c# - 在oracle的EF中,linq生成SQL时会发生数据类型转换,这使得SQL更加复杂,效率低下
- c - 如何在linux中使用审计来监控使用libaudit的文件
- node.js - 模块初始化错误:Object.fs.readFileSync (fs.js:551:33) 处的 Object.fs.openSync (fs.js:646:18) 错误
- android - 如何创建像谷歌日历这样在点击 Spinner 时展开的操作栏
- javascript - 如何使 jQuery 表格单元格(td)可单击以运行函数?