【问题标题】:Grails Domain Object ArrayList suddenly emptyGrails 域对象 ArrayList 突然为空
【发布时间】: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


【解决方案1】:

虽然我们遗漏了您编写的代码的某些部分,但上面的评论可能是正确的。

我将链接粘贴到 Grails 对象的保存方法: http://grails.org/doc/2.0.x/ref/Domain%20Classes/save.html

如果保存调用不起作用,请在 distributeTopics 方法中添加您检索对象的方式。

【讨论】:

  • 遗憾的是,保存调用不起作用。我在上面的sn-ps中添加了更多代码,以便您进一步查看
  • 我也不确定 ArrayList 映射。您是否尝试过: - 查看数据库中的内容? - 做一个不同的映射(grails.org/doc/1.3.7/guide/… Sets、Lists 和 Maps)并使用 hasMany 指令。
  • 我会尽快尝试并在此处发布反馈。
  • 我现在很忙,但在相关说明中,我的导师(监督这个项目)给我邮寄了以下内容,这似乎是我在这里遇到的 grails 中的一个错误:link 和 @ 987654324@,这似乎是同样的问题。不过,我会在几个小时后尝试您的建议。
  • 好的,我现在使用 HashMap 的一个非常丑陋的解决方法... 域类:HashMap studentOrder = new HashMap()。第一个整数只是位置编号,第二个整数是学生对象 ID。虽然这可行,但我仍然很好奇为什么这样一个整天使用的简单 ArrayList 无法正确序列化/保存......但是,非常感谢您(和@splix)的努力。
猜你喜欢
  • 1970-01-01
  • 2014-07-09
  • 1970-01-01
  • 2021-04-13
  • 1970-01-01
  • 1970-01-01
  • 2013-10-09
  • 1970-01-01
  • 2013-12-29
相关资源
最近更新 更多