【问题标题】:grails data binding collectiongrails 数据绑定集合
【发布时间】:2014-07-12 19:48:19
【问题描述】:

知道为什么 Grails 框架 - 参考文档中关于绑定到集合和映射的下一个示例失败并显示以下异常吗???

class Band {
    String name
    static hasMany = [albums: Album]
    List albums
}
class Album {
    String title
    Integer numberOfTracks
}

def bindingMap = [name: 'Genesis', 
                  'albums[0]': [title: 'Foxtrot', numberOfTracks: 6], 
                  'albums[1]': [title: 'Nursery Cryme', numberOfTracks: 7]]
def band = new Band(bindingMap)

assert band.name == 'Genesis'
assert band.albums.size() == 2
assert band.albums[0].title == 'Foxtrot'
assert band.albums[0].numberOfTracks == 6
assert band.albums[1].title == 'Nursery Cryme'
assert band.albums[1].numberOfTracks == 7


≫ groovy.lang.MissingPropertyException: No such property: albums[0] for class: Band Possible solutions: albums at Script1.run(Script1.groovy:15) at org.grails.plugins.console.ConsoleService.eval(ConsoleService.groovy:57) at org.grails.plugins.console.ConsoleService.eval(ConsoleService.groovy:37) at org.grails.plugins.console.ConsoleController.execute(ConsoleController.groovy:32) at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:198) at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63) at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53) at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49) at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:722) 

【问题讨论】:

    标签: grails grails-2.0


    【解决方案1】:

    如果你有这样的事情:

    专辑:

    // grails-app/domain/demo/Album.groovy
    package demo
    
    class Album {
        String title
        Integer numberOfTracks
    }
    

    乐队:

    // grails-app/domain/demo/Band.groovy
    package demo
    
    class Band {
        String name
        static hasMany = [albums: Album]
        List albums
    }
    

    此单元测试将通过:

    // test/unit/demo/BandSpec.groovy
    package demo
    
    import grails.test.mixin.TestFor
    import spock.lang.Specification
    
    @TestFor(Band)
    class BandSpec extends Specification {
    
        void "test constructor binding"() {
            given:
            def bindingMap = [name: 'Genesis',
                              'albums[0]': [title: 'Foxtrot', numberOfTracks: 6],
                              'albums[1]': [title: 'Nursery Cryme', numberOfTracks: 7]]
            when:
            def band = new Band(bindingMap)
    
            then:
            band.name == 'Genesis'
            band.albums.size() == 2
            band.albums[0].title == 'Foxtrot'
            band.albums[0].numberOfTracks == 6
            band.albums[1].title == 'Nursery Cryme'
            band.albums[1].numberOfTracks == 7
        }
    }
    

    该代码位于https://github.com/jeffbrown/bindingissue 的项目中。

    可能导致您看到的问题的一件事是Band 是否未被识别为域类。确保该类在 grails-app/domain/ 下定义。 Grails 提供的特殊数据绑定通常在构造函数中不可用。域类是一个例外。

    希望对你有帮助。

    【讨论】:

    • 如果Band 不是域类,那么hasMany 属性是没有意义的。如果它不是域类,那么您可以删除 hasMany 并且如果您想利用知道如何处理诸如“专辑 [0]”(以及一大堆其他功能)之类的数据绑定机制那么您不能使用构造函数,而是需要显式调用数据绑定器。例如,在控制器中,您可以调用类似bindData(bandInstance, bindingMap) 的名称,其中bandInstanceBand 类的实例,bindingMapMap,如上所述。
    • 确实在阅读参考文档的时候一定要多注意细节!!!在参考文档中说:以下代码显示了在域类中填充对象列表的简单示例......我在“域类”下划线。杰夫,你提到的两种情况都是绝对正确的:绑定域而不是域类,我已经对这两种情况进行了测试。非常感谢。
    • 听起来您在说您的Band 类不是域类。如果是这种情况,您可以删除 hasMany 声明,因为它在域类之外毫无意义。
    【解决方案2】:

    我猜问题在于 - 在您的绑定映射中 - 您选择将属性命名为“albums[0]”,而不是使用集合“albums”并为其提供两个条目。 Groovy 正在寻找一个列表,但您已将此表达式设为属性。首先创建相册,然后将它们添加到相册列表中。

    像这样:

    def bindingMap = [
      name: 'Genesis', 
      'albums': [
        [title: 'Foxtrot', numberOfTracks: 6], 
        [title: 'Nursery Cryme', numberOfTracks: 7]
      ]
    ]
    

    【讨论】:

    • 如果 Band 是域类,这是不正确的。域类构造函数知道如何处理 Map 中的“albums[0]”键。由于Band 定义了hasMany 属性,我假设它是一个域类。
    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    • 2011-01-03
    • 2012-06-14
    • 2011-05-14
    • 2010-11-25
    • 1970-01-01
    相关资源
    最近更新 更多