ASP.NET MVC Razor 视图引擎上的 Telerik Rad Grid - DetailView 最初未填充
好吧...我在这个问题上花了太多时间,所以我将其传递给专家 ->你。
我非常简单的 ASP.NET MVC(带有 Razor View Engine 的 v3)页面使用 Telerik Rad Grid 控件来显示一些类型列表,然后我在网格的 DetailsView 中显示相关代码。
做人口很容易。我有一个适用于 TypeCodeList 类型的 ViewModel,并将其发送到强类型视图以填充网格。这很好用……网格看起来很棒 - 感谢 Telerik。但是,我添加了 DetailsView,然后以相同的方式填充子 TypeCode。不好的是,当我的网格填充时,我选择左侧的三角形来展开树并查看子记录,但什么也没有。但是,如果我选择网格底部的“刷新”按钮,那么我可以点击三角形并显示子记录。
因此(总而言之),子记录不会在初始加载时显示。仅当我选择网格的 AJAX 刷新时,我才会获得子项。否则,它将按要求工作。
我一直在尝试查看是否可以在页面加载时通过 javascrip 以编程方式启动刷新。或者,如果我可以在选择时自行填充该内容而无需先进行刷新 - 那会更好。
下面是我的代码:
相关控制器代码(我已经取出了更新、删除、插入、日志记录和数据访问方法)
[HandleErrorWithElmah]
public partial class HostController : Controller
{
/// <summary>
/// Index - Home for HostController
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
return View();
}
#region Type List Section
/// <summary>
/// Gets the list of TypeLists - yea...say that again
/// </summary>
[GridAction]
public ActionResult TypeCodeList()
{
var model = GetActiveTypeLists();
// Get all of the type lists and send them to the view
return View(model);
}
/// <summary>
/// The ajaxified Select
/// </summary>
/// <returns></returns>
[AcceptVerbs(HttpVerbs.Post)]
[GridAction]
public ActionResult _TypeCodeList()
{
var model = GetActiveTypeLists();
return Json(new GridModel(model));
}
/// <summary>
/// Simply a wrapper to get all of the current type list values.
/// </summary>
/// <returns></returns>
private IEnumerable<TypeCodeListViewModel> GetActiveTypeLists()
{
var model = from p in entityRepository.Find<TypeList>(p => p.IsActive == true)
select new TypeCodeListViewModel
{
TypeListId = p.TypeListId,
Name = p.Name,
Description = p.Description,
IsActive = p.IsActive
};
return model;
}
#endregion
#region Type Code Section
[AcceptVerbs(HttpVerbs.Post)]
[GridAction]
public ActionResult _TypeCodeForTypeListAjax(int typeListId)
{
var model = GetActiveTypeCodes(typeListId);
return Json(new GridModel(model));
}
/// <summary>
/// Simply a wrapper to get all of the current type Code values.
/// </summary>
/// <returns></returns>
private IEnumerable<TypeCodeViewModel> GetAllActiveTypeCodes()
{
var model = from p in entityRepository.Find<OurLeaguePlay.Models.TypeCode>(p => p.IsActive == true).OrderBy(ord => ord.CodeName)
select new TypeCodeViewModel
{
TypeCodeId = p.TypeCodeId,
TypeListId = p.TypeListId,
CodeName = p.CodeName,
CodeValue = p.CodeValue,
Description = p.Description,
IsActive = p.IsActive
};
return model;
}
/// <summary>
/// Simply a wrapper to get all of the current type Code values.
/// </summary>
/// <returns></returns>
private IEnumerable<TypeCodeViewModel> GetActiveTypeCodes(int typeListId)
{
var model = from p in entityRepository.Find<OurLeaguePlay.Models.TypeCode>(p => p.IsActive == true &&
p.TypeListId == typeListId).OrderBy(ord => ord.CodeName)
select new TypeCodeViewModel
{
TypeCodeId = p.TypeCodeId,
TypeListId = p.TypeListId,
CodeName = p.CodeName,
CodeValue = p.CodeValue,
Description = p.Description,
IsActive = p.IsActive
};
return model;
}
#endregion
}
这是我的查看代码: (我已经删除了所有失败的 javascript 尝试,尝试强制页面加载。)
@model IEnumerable<TypeCodeListViewModel>
@using Telerik.Web.Mvc.UI
@using Telerik.Web.Mvc
@using OurLeaguePlay.ViewModels
@{Html.Telerik().Grid<TypeCodeListViewModel>(Model)
.Name("TypeLists")
.DetailView(details => details.ClientTemplate(
Html.Telerik().Grid<TypeCodeViewModel>()
.Name("TypeCode_<#= TypeListId #>")
.DataKeys(keys => keys.Add(k => k.TypeCodeId))
.Columns(columns =>
{
columns.Bound(o => o.CodeName).Width(40);
columns.Bound(o => o.CodeValue).ReadOnly(true).Width(40);
columns.Bound(o => o.Description).Width(100);
})
.DataBinding(dataBinding =>
{
dataBinding.Ajax().Select("_TypeCodeForTypeListAjax", "Host", new { typeListId = "<#= TypeListId #>" })
.Enabled(true);
}
)
.Pageable()
.Sortable()
.NoRecordsTemplate("No Type Codes exist for the selected Type List")
.ToHtmlString()
)
)
.DataKeys(keys => keys.Add(k => k.TypeListId))
.Columns(columns =>
{
columns.Bound(o => o.Name).Width(100);
columns.Bound(o => o.Description).Width(150);
columns.Command(commands =>
{
commands.Edit().ButtonType(GridButtonType.Image);
commands.Delete().ButtonType(GridButtonType.Image);
}
).Width(30);
})
.DataBinding(dataBinding =>
{
dataBinding.Ajax().Select("_TypeCodeList", "Host")
.Update("UpdateTypeList", "Host")
.Insert("InsertTypeList", "Host")
.Delete("DeleteTypeList", "Host")
.Enabled(true);
dataBinding.Server().Select("TypeCodeList", "Host", new { ajax = ViewData["ajax"] });
}
)
.Editable(editable => editable.Enabled(true).Mode(GridEditMode.InLine))
.Pageable(page => page.PageSize(10))
.Sortable()
.Selectable()
.Scrollable(scroll => scroll.Enabled(false))
.NoRecordsTemplate("No Type Lists can be retrieved from the database")
.ToolBar(commands => commands.Insert())
.Render();
}
最后...这里是 ViewModel 类:
public class TypeCodeListViewModel
{
[ScaffoldColumn(false)]
public int TypeListId { get; set; }
[Required(ErrorMessage = "Required")]
[StringLength(25, ErrorMessage = "Max Length is 25")]
public string Name { get; set; }
[Required(ErrorMessage = "Required")]
[StringLength(25, ErrorMessage="Max Length is 25")]
public string Description { get; set; }
[ScaffoldColumn(false)]
public bool IsActive { get; set; }
}
public class TypeCodeViewModel
{
[ScaffoldColumn(false)]
public int TypeCodeId { get; set; }
[ScaffoldColumn(false)]
public int TypeListId { get; set; }
[Required(ErrorMessage = "Required")]
[StringLength(25, ErrorMessage = "Max Length is 25")]
[DisplayName("Name")]
public string CodeName { get; set; }
[Required(ErrorMessage = "Required")]
[StringLength(25, ErrorMessage = "Max Length is 25")]
[DisplayName("Value")]
public string CodeValue { get; set; }
[StringLength(500, ErrorMessage = "Max Length is 500")]
public string Description { get; set; }
[ScaffoldColumn(false)]
public bool IsActive { get; set; }
}
OK...I've spent too much time floundering on this one, so I'm passing it on to the experts -> YOU.
My VERY simple ASP.NET MVC (v3 with Razor View Engine) page uses a Telerik Rad Grid control to show some type lists and then I have the associated codes showing in the DetailsView of the grid.
Doing the population is easy. I have a ViewModel for my TypeCodeList type and send it to the strongly typed view to populate the grid. This works GREAT...and the grid looks great - thanks Telerik. However, I added the DetailsView to then populate the child TypeCodes in the same manner. The bad thing is that when my grid populates, I select the triangle on the left to expand the tree and see the child records, nothing is there. BUT, if I select the "Refresh" button on the bottom of the grid, THEN I can hit the triangle and the child records display.
So (in summary), the child records do not show up on the initial load. Only when I select an AJAX refresh of the grid I get the children. Otherwise, it works as required.
I have been trying to see if I can programmatically kick off the refresh via javascrip upon page load. OR if I can get the thing to populate by itself when selected without doing a refresh first - that would be preferable.
Below is my code:
Pertinent Controller Code (I've taken out the update, delete, insert, logging and data access methods)
[HandleErrorWithElmah]
public partial class HostController : Controller
{
/// <summary>
/// Index - Home for HostController
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
return View();
}
#region Type List Section
/// <summary>
/// Gets the list of TypeLists - yea...say that again
/// </summary>
[GridAction]
public ActionResult TypeCodeList()
{
var model = GetActiveTypeLists();
// Get all of the type lists and send them to the view
return View(model);
}
/// <summary>
/// The ajaxified Select
/// </summary>
/// <returns></returns>
[AcceptVerbs(HttpVerbs.Post)]
[GridAction]
public ActionResult _TypeCodeList()
{
var model = GetActiveTypeLists();
return Json(new GridModel(model));
}
/// <summary>
/// Simply a wrapper to get all of the current type list values.
/// </summary>
/// <returns></returns>
private IEnumerable<TypeCodeListViewModel> GetActiveTypeLists()
{
var model = from p in entityRepository.Find<TypeList>(p => p.IsActive == true)
select new TypeCodeListViewModel
{
TypeListId = p.TypeListId,
Name = p.Name,
Description = p.Description,
IsActive = p.IsActive
};
return model;
}
#endregion
#region Type Code Section
[AcceptVerbs(HttpVerbs.Post)]
[GridAction]
public ActionResult _TypeCodeForTypeListAjax(int typeListId)
{
var model = GetActiveTypeCodes(typeListId);
return Json(new GridModel(model));
}
/// <summary>
/// Simply a wrapper to get all of the current type Code values.
/// </summary>
/// <returns></returns>
private IEnumerable<TypeCodeViewModel> GetAllActiveTypeCodes()
{
var model = from p in entityRepository.Find<OurLeaguePlay.Models.TypeCode>(p => p.IsActive == true).OrderBy(ord => ord.CodeName)
select new TypeCodeViewModel
{
TypeCodeId = p.TypeCodeId,
TypeListId = p.TypeListId,
CodeName = p.CodeName,
CodeValue = p.CodeValue,
Description = p.Description,
IsActive = p.IsActive
};
return model;
}
/// <summary>
/// Simply a wrapper to get all of the current type Code values.
/// </summary>
/// <returns></returns>
private IEnumerable<TypeCodeViewModel> GetActiveTypeCodes(int typeListId)
{
var model = from p in entityRepository.Find<OurLeaguePlay.Models.TypeCode>(p => p.IsActive == true &&
p.TypeListId == typeListId).OrderBy(ord => ord.CodeName)
select new TypeCodeViewModel
{
TypeCodeId = p.TypeCodeId,
TypeListId = p.TypeListId,
CodeName = p.CodeName,
CodeValue = p.CodeValue,
Description = p.Description,
IsActive = p.IsActive
};
return model;
}
#endregion
}
Here is my View Code:
(I've taken out all of my failed javascript attempts to try and force the load on page load.)
@model IEnumerable<TypeCodeListViewModel>
@using Telerik.Web.Mvc.UI
@using Telerik.Web.Mvc
@using OurLeaguePlay.ViewModels
@{Html.Telerik().Grid<TypeCodeListViewModel>(Model)
.Name("TypeLists")
.DetailView(details => details.ClientTemplate(
Html.Telerik().Grid<TypeCodeViewModel>()
.Name("TypeCode_<#= TypeListId #>")
.DataKeys(keys => keys.Add(k => k.TypeCodeId))
.Columns(columns =>
{
columns.Bound(o => o.CodeName).Width(40);
columns.Bound(o => o.CodeValue).ReadOnly(true).Width(40);
columns.Bound(o => o.Description).Width(100);
})
.DataBinding(dataBinding =>
{
dataBinding.Ajax().Select("_TypeCodeForTypeListAjax", "Host", new { typeListId = "<#= TypeListId #>" })
.Enabled(true);
}
)
.Pageable()
.Sortable()
.NoRecordsTemplate("No Type Codes exist for the selected Type List")
.ToHtmlString()
)
)
.DataKeys(keys => keys.Add(k => k.TypeListId))
.Columns(columns =>
{
columns.Bound(o => o.Name).Width(100);
columns.Bound(o => o.Description).Width(150);
columns.Command(commands =>
{
commands.Edit().ButtonType(GridButtonType.Image);
commands.Delete().ButtonType(GridButtonType.Image);
}
).Width(30);
})
.DataBinding(dataBinding =>
{
dataBinding.Ajax().Select("_TypeCodeList", "Host")
.Update("UpdateTypeList", "Host")
.Insert("InsertTypeList", "Host")
.Delete("DeleteTypeList", "Host")
.Enabled(true);
dataBinding.Server().Select("TypeCodeList", "Host", new { ajax = ViewData["ajax"] });
}
)
.Editable(editable => editable.Enabled(true).Mode(GridEditMode.InLine))
.Pageable(page => page.PageSize(10))
.Sortable()
.Selectable()
.Scrollable(scroll => scroll.Enabled(false))
.NoRecordsTemplate("No Type Lists can be retrieved from the database")
.ToolBar(commands => commands.Insert())
.Render();
}
Finally...here are the ViewModel classes:
public class TypeCodeListViewModel
{
[ScaffoldColumn(false)]
public int TypeListId { get; set; }
[Required(ErrorMessage = "Required")]
[StringLength(25, ErrorMessage = "Max Length is 25")]
public string Name { get; set; }
[Required(ErrorMessage = "Required")]
[StringLength(25, ErrorMessage="Max Length is 25")]
public string Description { get; set; }
[ScaffoldColumn(false)]
public bool IsActive { get; set; }
}
public class TypeCodeViewModel
{
[ScaffoldColumn(false)]
public int TypeCodeId { get; set; }
[ScaffoldColumn(false)]
public int TypeListId { get; set; }
[Required(ErrorMessage = "Required")]
[StringLength(25, ErrorMessage = "Max Length is 25")]
[DisplayName("Name")]
public string CodeName { get; set; }
[Required(ErrorMessage = "Required")]
[StringLength(25, ErrorMessage = "Max Length is 25")]
[DisplayName("Value")]
public string CodeValue { get; set; }
[StringLength(500, ErrorMessage = "Max Length is 500")]
public string Description { get; set; }
[ScaffoldColumn(false)]
public bool IsActive { get; set; }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
嗯...我想我自己解决了...它就像让网格绑定自身一样简单,而不是通过在页面初始显示时调用的非ajax 方法强制将数据放入其中。
该
函数应该简单地更新为以下内容:
没有 [GridAction] 装饰器。
如果您不强制将值放入网格中,它将使用 Ajax 方法绑定自身,然后子网格将在扩展时填充。
Well...I think I figured it out on my own...it was as simple as just letting the grid bind itself and not forcing data into it via the non-ajax method that gets called upon initial display of the page.
The
function should simply be updated to the following:
with no [GridAction] decorator.
If you don't force values into the grid, it will bind itself using the Ajax method and then the child grids will populate upon expansion.