【发布时间】:2012-01-25 21:30:10
【问题描述】:
我目前正在开发一个 grails 1.3.7 应用程序,它将用于组织讲座、研讨会和与大学相关的活动。在这种情况下,导师应该能够分配学生先前选择的主题。为此,我使用了一个简单的表格“矩阵”,右侧有学生,可用主题作为表格标题。现在导师要我实现,表格行是可拖动的。我使用 jQuery 插件实现了这一点,一切正常,但我还必须将新的行顺序保存在某处,因此我决定将其保存为域类中的 ArrayList。我实现了一个简单的逻辑来擦除列表并在每次导师保存主题作业时重建它。
这些步骤的代码:
域类
class Seminar extends AbstractLecture {
...
ArrayList<Integer> studentOrder = new ArrayList<Integer>()
...
gsp: hiddenField 保存新行顺序的序列化表示,由 javascript 函数设置(工作正常)。
<g:form action="saveDistribution">
<g:hiddenField name="order" id="order" value=""/>
...
控制器
插件序列化函数返回一个我在这里分解的字符串,这也没有问题,并且ID正确包含在此块之后的列表中。
def saveDistribution = {
....
if (!params.order.toString().equals("")) {
seminar.studentOrder.clear() //seminar is the domain object
def temp = params.order.toString().replace('[','').replace(']','').replace("table-1=", "").replaceFirst('&', '')
def split = temp.split("&")
for (id in split) {
seminar.studentOrder.push(Integer.parseInt(id)) //Works fine
}
}
//If I check seminar.studentOrder here, the parsed values are present
//Now I redirect to another function (forward would also work, doesn't matter here)
redirect(action: "distributeTopics", id: params.id)
但是现在最大的问题是:当我在重定向后立即检查seminar.studentOrder 时,列表完全是空的……我真的,真的不知道为什么。在过去的几个小时里,我几乎把我逼疯了:( 我尝试了我什至可以想象的一切来解决这个问题,但没有任何东西愿意工作。 现在我被敦促认为我在某个地方遗漏了重要的一点。
感谢您为解决此问题所做的一切。 如果您需要更多代码,甚至此上下文的完整代码,我会提供。
提前非常感谢, 多米尼克
更新(为两个控制器功能添加了完整代码):
这是来自distributeTopics的代码:
TopicTableDataWrapper 类是一个简单的 Java 类,用于收集必要的数据,以便我在 gsp 中过得更轻松。
正如你所看到的,我只是从 ArrayList studentOrder 提供的 ID 从数据库中提取学生对象,但由于列表始终为空并且保存也不起作用......好吧,我被困在这里。
def distributeTopics = {
def seminar = Seminar.findById(params.id)
if (!seminar) {
flash.message = "Error: Seminar not found. (Database error?)"
redirect(controller: "lecture", action: "list")
}
/*
* Gather all students and build an ArrayList<TopicTableDataWrapper>, which will be passed to the gsp.
*/
def wrapperList = new ArrayList<TopicTableDataWrapper>()
if (seminar.studentOrder.isEmpty()) {
for (student in seminar.students) {
//Selected topics
def topics = seminar.getPrioritizedTopics(student)
if (topics[0] == null) {
topics = null
}
//Already assigned topic
def assigned = seminar.getAssignedTopic(student)
//Comment
def comment = null
if (seminar.comments.containsKey(student.id.toString())) {
comment = seminar.comments.get(student.id.toString())
}
wrapperList.push(new TopicTableDataWrapper(student, assigned, comment, topics))
}
}
else {
for (studentId in seminar.studentOrder) {
def student = User.findById(studentId)
if (student == null) continue
//Selected topics
def topics = seminar.getPrioritizedTopics(student)
if (topics[0] == null) {
topics = null
}
//Possibly assigned topic
def assigned = seminar.getAssignedTopic(student)
//Comment
def comment = null
if (seminar.comments.containsKey(student.id.toString())) {
comment = seminar.comments.get(student.id.toString())
}
wrapperList.push(new TopicTableDataWrapper(student, assigned, comment, topics))
}
}
/*
* Now we also need a list of all topics.
* It is important that the list is sorted, because we must map the topic titles to the shortcuts in the gsp!
* We do this by building a hashmap which just maps 'T1', 'T2', ... as keys to the topics
*/
def topicList = seminar.topics.sort()
def map = new HashMap<String, Topic>()
def i = 1
for (topic in topicList) {
map.put("T" + i.toString(), topic)
i++
}
[seminar: seminar, wrapperList: wrapperList, topicMap: map, id: seminar.id]
}
def saveDistribution = {
def seminar = Seminar.findById(params.id)
if (!seminar) {
flash.message = "There was a problem while retrieving the seminar (database error?)."
redirect(controller: "lecture", action: "list")
}
/*
* Parse the corresponding radiogroup for every student in the seminar
*/
for (student in seminar.students) {
//Look if a topic has been assigned by checking the params -> "group <student.id>"
if (params.containsKey("group " + student.id)) {
//if that's the case, assign him this topic, but keep his selection for later corrections!
def topic = Topic.findById(Integer.parseInt(params.get("group " + student.id).toString()))
//Remove previously assigned topic for this seminar
def prevTopic = seminar.getAssignedTopic(student)
if (prevTopic != null) {
student.removeFromAssignedTopics(prevTopic)
}
student.addToAssignedTopics(topic)
}
}
if (!params.order.toString().equals("")) {
seminar.studentOrder.clear()
def temp = params.order.toString().replace('[','').replace(']','').replace("table-1=", "").replaceFirst('&', '')
def splitParam = temp.split("&")
for (id in splitParam) {
seminar.studentOrder.push(Integer.parseInt(id))
}
}
flash.message = "Distribution saved."
seminar.save(failOnError: true) //Still empty list after redirect
redirect(action: "distributeTopics", id: params.id)
}
【问题讨论】:
-
你确定你在重定向之前调用
.save()吗? (此示例中不存在)。如果叫它.save(failOnError: true)呢? -
这也不起作用,重定向后列表中的 Integer 对象仍然消失。在发布问题之前,我昨天还尝试了几种 .save 可能性,但实际上,没有任何效果。
-
你能用
.save()方法显示你的控制器代码吗? -
好了,添加了完整的代码。
-
您之前是否尝试过在其他地方保存它,也许是在 Bootstrap 中?你能改用
List studentOrder = []吗?
标签: grails