2011-08-27 79 views
1

在我的Grails應用程序,我有這樣的枚舉:Grails的綁定集合枚舉

public enum RelationshipStatus{ 

    Single_Never_Married, 
    Separated, 
    Divorced, 
    Widowed; 
} 

我定義這個命令對象:

class MyCommand { 
    List<RelationshipStatus> relationshipStatuses 
} 

,我在我的控制器動作

一個使用
def myAction = {MyCommand myCommand -> 
} 

當我提交一個請求到這個動作的參數

user.relationshipStatuses=Separated&user.relationshipStatuses=Divorced 

我預計myCommand.relationshipStatuses將包含RelationshipStatus.SeparatedRelationshipStatus.Divorced,但實際上它是空的。

我的理解是,Grails根據枚舉的名稱自動執行請求參數 - >枚舉轉換。只要將它區分它不,我試圖定義一個屬性編輯器,做這種轉換:

class RelationshipStatusEnumEditor extends PropertyEditorSupport {  

    public String getAsText() { 
     value.name() 
    } 

    public void setAsText(String text) { 
     RelationshipStatus.valueOf(text) 
    } 
} 

我註冊這個編輯器使用Grails/Spring和再次嘗試,但結果是一樣的。是否可以將請求參數綁定到Enum的Collection

+0

我相信,Grails不知道如何填充你的列表,因爲它放棄了列表類型(List )上的信息。我不確定,如果可能的話。 – sbglasius

回答

1

使用Grails的2.3引入了DataBinder的,我想出了以下解決方案轉換請求參數來收集的枚舉。例如,考慮到這些枚舉

enum Gender { 
    MALE, FEMALE 
} 

enum Season { 
    SPRING, SUMMER, AUTUMN, WINTER 
} 

和該命令對象

class MyCommand { 
    Collection<Gender> genders 
    Collection<Season> seasons 
} 

,我們假定我們要轉換爲字符串像"MALE,FEMALE""SPRING,SUMMER,WINTER"到相應的枚舉集合。首先,提供FormattedValueConverter的實現,確實

class EnumCollectionConverter implements FormattedValueConverter { 

    /** 
    * To make other enums bindable, just add them to this list 
    */ 
    private static final List<Class<Enum>> convertableEnums = [Gender, Season] 

    @Override 
    Object convert(value, String format) { 

     Class<Enum> targetEnumClass = convertableEnums.find { it.simpleName == format } 

     if (targetEnumClass) { 
      List<String> enumConstantNames = value.toString().tokenize(',') 
      return enumConstantNames.collect { targetEnumClass.valueOf(it) } 
     } 
     value 
    } 

    @Override 
    Class<?> getTargetType() { 

     // this class converts to a Collection<T extends Enum<T>> but the return value 
     // of this method can't be any more specific than Collection due to type erasure 
     Collection 
    } 
} 

然後註冊EnumCollectionConverterresources.groovy一個Spring bean轉換 - 沒關係什麼名字,你選擇這個bean。然後使用類以上用逗號分隔的字符串轉換爲NUM集合,

class MyCommand { 
    @BindingFormat('Gender') 
    Collection<Gender> genders 

    @BindingFormat('Season') 
    Collection<Season> seasons 
} 

註釋相關屬性傳遞給@BindingFormat值應該是將存儲在枚舉類型的簡單名稱綁定的集合。

0

正如我所知,如果它是空的,默認情況下grails不會填充List屬性。只有它已經存在,並且項目的索引被傳遞。

嘗試定義這個屬性爲:

import org.apache.commons.collections.ListUtils 
import org.apache.commons.collections.Factory 

class MyCommand { 
    List<RelationshipStatus> relationshipStatuses = ListUtils.lazyList([],{new RelationshipStatus()} as Factory) 
} 

,並提交參數爲:

user.relationshipStatuses[0]=Separated&user.relationshipStatuses[1]=Divorced