Grails:在另一个闭包中使用多个闭包

Grails: Use several closures inside another one

我正在根据几个因素创建一个标准。目前我通过以下方式使用嵌套闭包:

Utils.groovy

static def statusAndOrderCriteria = { x ->
    ...
    Utils.commonOrderCriteria.delegate = delegate
    Utils.commonOrderCriteria(x)
}

static def commonOrderCriteria = { x ->
    ...
}

用法:

Alert.createCriteria().list({
    Utils.statusAndOrderCriteria.delegate = delegate
    Utils.statusAndOrderCriteria(x)
})

我想使用几个闭包,例如:

Alert.createCriteria().list({
    Utils.firstCriteria(a)
    Utils.secondCriteria(b)
    Utils.statusAndOrderCriteria(x)
})

我不知道如何实现。我知道我不能在同一个闭包中多次覆盖委托对象。

构建 GORM 条件查询时,闭包的委托是 HibernateCriteriaBuilder 的一个实例。您可以做的是修改 Util 闭包以接受此构建器作为参数。然后,将方法调用委托给构建器。这是一个例子:

class Utils {
    static def statusAndOrderCriteria = { criteriaBuilder, x ->
        criteriaBuilder.eq('foo', x)
        Utils.commonOrderCriteria(criteriaBuilder, x)
    }

    static def commonOrderCriteria = { criteriaBuilder, x ->
        criteriaBuilder.lt('bar', x)
    }
}

然后你可以像这样在Util中使用静态闭包:

Alert.createCriteria().list({
    Utils.firstCriteria(delegate, a)
    Utils.secondCriteria(delegate, b)
    Utils.statusAndOrderCriteria(delegate, x)
})

提示:如果闭包不是静态属性,您将能够避免不断地传递委托,如下所示:

@groovy.transform.TupleConstructor
class Utils {
    HibernateCriteriaBuilder criteriaBuilder

    def statusAndOrderCriteria = { x ->
        criteriaBuilder.foo()
        Utils.commonOrderCriteria(x)
    }

    def commonOrderCriteria = { x ->
        criteriaBuilder.bar()
    }
}

Alert.createCriteria().list({
    def utils = new Utils(delegate)

    utils.firstCriteria(a)
    utils.secondCriteria(b)
    utils.statusAndOrderCriteria(x)
})