2011-06-30 19 views
2

Telerik MVCグリッドコンポーネントを使用して、グループ化可能なグリッドにajaxを使用してレンダリングしています。グリッドは細かい並べ替えやページングをレンダリングしますが、Ajaxのリフレッシュは機能しますが、グループ化を行おうとするとレンダリングがすべて失敗します。添付されているのは、グリッドのスクリーンキャップで、グループ化の前後にあります。Telerik MVCグリッドが適切にグループ化されていません

グリッドの定義は非常に単純明快です:

<div id="tabAccounts" class="tab_content"> 
    @(Html.Telerik().Grid<SharedSimpleAccountListViewModel>() 
      .Name("AcctGrid") 
      .Columns(columns => 
      { 
       columns.Bound(x => x.Number) 
        .HeaderHtmlAttributes(new { @style = "text-align: center;" }) 
        .HtmlAttributes(new { @style = "text-align: center;" }); 
       columns.Bound(x => x.ProviderOrganizationFriendlyName) 
        .Title("Provider"); 
       columns.Bound(x => x.Name) 
        .Title("Account Name"); 
       columns.Bound(x => x.BillingLocationName) 
        .Title("Location"); 
      }) 
      .Groupable() 
      .DataBinding(db => db.Ajax().Select("CustomerAccounts", "Customers", new { id = Model.Id })) 
      .Pageable(pager => pager.PageSize(50)) 
      .Sortable() 
    ) 
</div> 

コントローラのアクションは、(それだけで検索がリポジトリからだから、私は貼り付けられません)もストレートフォワードです。 Telerikのデフォルトテーマを使用しているので、カスタムCSSはありません。必要なスクリプトがページに含まれていることを確認しました。

グループ化後にHTMLを調べると、テーブルに変更が加えられたように見えますが、グループのテーブル行要素は追加されていません。グループ化の試行後に存在するHTMLは次のとおりです。

<table cellspacing="0"> 
    <colgroup> 
     <col class="t-group-col"> 
      <col><col><col><col> 
     </colgroup> 
    <thead class="t-grid-header"> 
     <tr> 
      <th class="t-group-cell t-header"> </th> 
      <th style="text-align: center;" scope="col" class="t-header"> 
       <a href="/Customers/Details/408?AcctGrid-orderBy=Number-asc" class="t-link">Number</a> 
      </th> 
      <th scope="col" class="t-header"> 
       <a href="/Customers/Details/408?AcctGrid-orderBy=ProviderOrganizationFriendlyName-asc" class="t-link">Provider</a> 
      </th> 
      <th scope="col" class="t-header"> 
       <a href="/Customers/Details/408?AcctGrid-orderBy=Name-asc" class="t-link">Account Name</a> 
      </th> 
      <th scope="col" class="t-header t-last-header"> 
       <a href="/Customers/Details/408?AcctGrid-orderBy=BillingLocationName-asc" class="t-link">Location</a> 
      </th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr> 
      <td style="text-align: center;">00002</td> 
      <td>Acme</td> 
      <td>Test account 2 </td> 
      <td class="t-last">Location 2</td> 
     </tr> 
     <tr class="t-alt"> 
      <td style="text-align: center;">00001</td> 
      <td>3M</td> 
      <td>Test account 1</td> 
      <td class="t-last">Location 1</td> 
     </tr> 
    </tbody> 
</table> 

何が起こっているのでしょうか?

+0

どこの画面に表示されますか – Tassadaque

+0

おっと...私はTelerikにクロス投稿し、コピーする前にはスクラブしませんでした。私はそれ以来、私はそれをここに掲載できるようになる前に、それを整理しなければならない解決策を考え出しました。 –

+0

@Jush、Ahem ..これには解決策がありますか?私はそれを見たいと思う。 – Levitikon

答えて

3

問題の要点は、私がAJAXバインドを行っていたが、グループ化とソートを行いたいということだった。必要なものは、最初にグループ化された列、次に他の並べ替えられた列によってソートされる手動のソート処理でした。その後、グリッドはグループUIを設定します。私のプロジェクトでは、NHibernateをORMとして使用しているため、クエリーを処理するかなり堅牢なサービス層を使用していたため、これは少し難題でした。私はこのようになりますヘルパークラスで動作するようにグリッドを得ることになった:私のドメインオブジェクトは、タイプAddressの性質を持っているので、もし私は、プロパティ名を平坦化されているのviewmodelsを使用してい

public static class TelerikGridHelpers 
{ 
    public static IEnumerable<AggregateFunctionsGroup> BuildInnerGroup<T, TObject>(IEnumerable<TObject> group, Func<TObject, T> groupSelector, Func<IEnumerable<TObject>, IEnumerable> innerSelector) 
    { 
     return group.GroupBy(groupSelector) 
       .Select(i => new AggregateFunctionsGroup 
       { 
        Key = i.Key, 
        Items = innerSelector(i) 
       }); 
    } 

    public static Func<IEnumerable<TObject>, IEnumerable<AggregateFunctionsGroup>> BuildGroup<T, TObject>(Func<TObject, T> groupSelector, Func<IEnumerable<TObject>, IEnumerable<AggregateFunctionsGroup>> selectorBuilder) 
    { 
     var tempSelector = selectorBuilder; 
     return g => g.GroupBy(groupSelector) 
        .Select(c => new AggregateFunctionsGroup 
        { 
         Key = c.Key, 
         HasSubgroups = true, 
         Items = tempSelector.Invoke(c).ToList() 
        }); 
    } 

    public static IEnumerable<AggregateFunctionsGroup> ApplyGrouping<T>(IQueryable<T> data, IList<GroupDescriptor> groupDescriptors) 
    { 
     Func<IEnumerable<T>, IEnumerable<AggregateFunctionsGroup>> selector = null; 
     foreach (var descriptor in groupDescriptors.Reverse()) 
     { 
      var tempDescriptor = descriptor; 
      if (selector == null) 
       selector = g => BuildInnerGroup(g.Select(p => p), p => p.GetType().GetProperty(tempDescriptor.Member).GetValue(p, null), i => i.ToList()); 
      else 
       selector = BuildGroup(p => p.GetType().GetProperty(tempDescriptor.Member).GetValue(p, null), selector); 
     } 

     return selector != null 
        ? selector.Invoke(data).ToList() 
        : null; 
    } 

    public static List<Order> GenerateOrderList<T>(this T translator, GridCommand command) where T : IPropertyNameTranslator 
    { 
     var orders = new List<Order>(); 
     // Step 1 is to add the grouping orders 
     if (command.GroupDescriptors.Any()) 
      orders.AddRange(from descriptor in command.GroupDescriptors 
          let sortField = translator.TranslatePropertyToDomainProperty(descriptor.Member) 
          select descriptor.SortDirection == ListSortDirection.Ascending ? Order.Asc(sortField) : Order.Desc(sortField)); 

     // Then the sorting 
     if (command.SortDescriptors.Any()) 
      orders.AddRange(from descriptor in command.SortDescriptors.Where(c => !command.GroupDescriptors.Where(g => g.Member == c.Member).Any()) 
          let sortField = translator.TranslatePropertyToDomainProperty(descriptor.Member) 
          select descriptor.SortDirection == ListSortDirection.Ascending ? Order.Asc(sortField) : Order.Desc(sortField)); 

     return orders; 
    } 

    public static List<ViewOrder> GenerateViewOrderList<T>(this T translator, GridCommand command) where T : IPropertyNameTranslator 
    { 
     var orders = new List<ViewOrder>(); 
     // Step 1 is to add the grouping orders 
     if (command.GroupDescriptors.Any()) 
      orders.AddRange(from descriptor in command.GroupDescriptors 
          let sortField = translator.TranslatePropertyToDomainProperty(descriptor.Member) 
          select new ViewOrder { PropertyName = sortField, Ascending = descriptor.SortDirection == ListSortDirection.Ascending}); 

     // Then the sorting 
     if (command.SortDescriptors.Any()) 
      orders.AddRange(from descriptor in command.SortDescriptors.Where(c => !command.GroupDescriptors.Where(g => g.Member == c.Member).Any()) 
          let sortField = translator.TranslatePropertyToDomainProperty(descriptor.Member) 
          select new ViewOrder { PropertyName = sortField, Ascending = descriptor.SortDirection == ListSortDirection.Ascending }); 

     return orders; 
    } 

} 

注意、 ViewModelのプロパティ名はAddressStreetAddressCityです。私のIPropertyTranslatorインターフェイスは、GridCommandオブジェクト内の文字列ソートメンバー名から、私のドメインが期待するものに行くことができる翻訳プロセスを指定します。

最後の2番目のメソッドのOrderクラスはNHibernate Orderです。このメソッドを使用して、結果を取得するときにサービスレイヤに渡すオブジェクトOrderのリストを生成します。 ViewOrderはUIで使用するユーティリティクラスです。私はまだそれらの最後の2つのメソッドをリファクタリングする必要があるので、それらは繰り返している。ここで

は、私はグリッドのGridModelを引っ張っているヘルパークラスを使用する方法の例です:

public GridModel GetAllOrdersGrid(GridCommand command) 
    { 
     var svc = DependencyResolver.Current.GetService<IOrderService>(); 

     var propertyTranslator = new OrdersViewModelTranslator(); 
     var orders = 
      propertyTranslator.GenerateOrderList(command).ToList(); 

     IFutureValue<long> total; 
     var orders = svc.FindAll(((command.Page - 1) * command.PageSize), command.PageSize, orders, out total); 

     var mapper = new Mapper<DomainOrder, OrdersViewModel>(); 
     var viewModels = orders.Select(mapper.MapToViewModel); 


     return command.GroupDescriptors.Any() 
        ? new GridModel 
        { 
         Data = TelerikGridHelpers.ApplyGrouping(viewModels.AsQueryable(), command.GroupDescriptors), 
         Total = Convert.ToInt32(total.Value) 
        } 
        : new GridModel { Data = viewModels, Total = Convert.ToInt32(total.Value) }; 
    } 

ビットがそこにありますそれは、グループ化の全体の問題とは無関係だが、それが現実の世界の例ですが、多分それは助けになるでしょう。

+0

素敵なもの!本当に助けてくれた –

関連する問題