2014-02-17 105 views
0

我有一個擁有大約50個屬性的類,這個類的實例被添加到列表中。這個列表然後被添加到Velocity上下文中。現在,我想分類這些數據。在分析模板之前,哪個字段或者是否升序或降序是未知的。在Nvelocity中實現排序

資源,我看着:

Better way to use Velocity's GenericTools in a Standalone app?

Velocity foreach sort list

http://velocity.apache.org/tools/devel/generic/

基於上市這裏,我不能找出如何解決這一資源。 GenericTools是否可用於Castle的Nvelocity?如果不是,我怎麼能實現我在這裏要求的這種通用排序?

回答

0

我的解決方案是寫我自己的排序類,並將其作爲上下文添加到nvelocity。我將字段傳遞爲字符串並將其作爲反射訪問。我還設置按字符串值升序或降序排序。我也傳入比較器的名稱並通過反射訪問它。然後,我使用帶選擇字段和比較器的List方法OrderBy或OrderByDescending。

我在這裏找到的部分代碼:http://zootfroot.blogspot.co.uk/2009/10/dynamic-linq-orderby.html

public class NvelocitySort 
{ 
    public List<MyObject> Sort(List<MyObject> list, string fieldAndMode, string comparerName) 
    { 
     fieldAndMode = fieldAndMode.Trim(); 

     // Split the incoming string to get the field name and sort ascending or descending 
     string[] split = fieldAndMode.Split(' '); 
     // Set default sort mode 
     string mode = "asc"; 
     // If sort mode not specified, this will be the field name 
     string field = fieldAndMode; 
     // If sort mode added split length shall be 2 
     if (split.Length == 2) 
     { 
      field = split[0]; 
      if (split[1].ToLower() == "asc" || split[1].ToLower() == "ascending") mode = "asc"; 
      if (split[1].ToLower() == "desc" || split[1].ToLower() == "descending") mode = "desc"; 
     } 
     // If length is more than 2 or 0, return same list as passed in 
     else if (split.Length > 2 || split.Length == 0) 
     { 
      return list; 
     } 

     // Get comparer based on comparer name 
     IComparer<string> comparer = (IComparer<string>)Activator.CreateInstance(Type.GetType(string.Format("Namespace.{0}", comparerName))); 

     // Choose the sort order 
     if (mode == "asc") 
      return list.OrderBy(item => item.GetReflectedPropertyValue(field), comparer).ToList(); 
     if (mode == "desc") 
      return list.OrderByDescending(item => item.GetReflectedPropertyValue(field), comparer).ToList(); 

     // If sort order not asc/desc return same list as passed in 
     return list; 
    } 
} 

這是檢索領域的反射法。

public static string GetReflectedPropertyValue(this object subject, string field) 
{ 
    object reflectedValue = subject.GetType().GetProperty(field).GetValue(subject, null); 
    return reflectedValue != null ? reflectedValue.ToString() : ""; 
} 

簡單的比較器例如:

public class TextComparer : IComparer<string> 
{ 
    public int Compare(string x, string y) 
    { 
     return string.Compare(x, y); 
    } 
} 

加入Nvelocity背景是這樣的:

this.velocityContext.Put("sorter", new NvelocitySort()); 

從Nvelocity模板訪問的是這樣的:

#foreach($item in $sorter.Sort($listObject, "Name desc", "TextComparer")) 
$item.Name 
#end 

希望它可以幫助別人其他...

編輯: 找到一個更好的辦法做到這一點(實現多個字段排序): http://www.codeproject.com/Articles/280952/Multiple-Column-Sorting-by-Field-Names-Using-Linq