我试图使用递归帮助器在Umbraco中创建一个多级下拉菜单,由于某种原因,我收到一个编译错误,说我在将根元素的子级传递给帮助器时传递了错误的参数。
我找到了一些解决方案,但是他们不使用帮助程序,所以我不知道问题出在帮助程序还是我做错了什么。
我的代码是:
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{ var selection = CurrentPage.Site().Children.Where("Visible"); }
<div class="fleft menu_area">
<button class="btn btn-primary visible-xs" type="button" data- toggle="collapse" data-target="#mainMenu" aria-expanded="false" aria- controls="mainMenu"> <i class="glyphicon glyphicon-th-large"></i> Menu </button>
<div class="collapse navbar-collapse" id="mainMenu">
<ul class="nav navbar-nav">
@CreateListItems(selection)
</ul>
</div>
</div>
@helper CreateListItems(Umbraco.Web.Models.DynamicPublishedContentList collection)
{
foreach (var item in collection)
{
if (item.Children.Where("Visible").Count() > 0)
{
<li class="menuOption dropdown @(item.IsAncestorOrSelf(CurrentPage) ? "current" : null)" data-menu- id="@item.GetPropertyValue("menuOptionIdentifier")">
<a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" href="@item.Url">@item.Name</a>
<ul class="dropdown-menu">
@{
CreateListItems(item.Children.Where("Visible")); // THE PROBLEM IS HERE
}
</ul>
</li>
}
else
{
<li class="@(item.IsAncestorOrSelf(CurrentPage) ? "current" : null)"><a href="@item.Url">@item.Name</a></li>
}
}
}
我已经看到
item.Children.Where("Visible")
返回一个iQueryable,所以我尝试将其分配给一个变量,并且该变量是正确的DynamicPublishedContentList类型。我将该变量传递给了帮助程序,但出现了同样的错误。我已经尝试过使用其他版本的helper之外的foreachs,而是通过传递DynamicPublishedContentList传递了DynamicPublishedContentItem,但是我也无法使其正常工作,我遇到了同样的错误。
我尝试将Where结果转换为列表,但是我也收到一个错误,说一个IQueryable
does not contain a definition for 'ToList'
不能这样做抚养这些孩子的正确方法是什么?
有任何想法吗?
最佳答案
你是对的。问题是您正在尝试将IQueryable
传递给DynamicPublishedContentList
。我只是将其全部切换为动态,因此您不必担心具体传递了什么。如果要进行动态处理,则最好避免必须处理所有类型转换。
从Where("Visible")
的调用中收到混合消息的原因是dynamic
不仅仅是常规类型。它基本上标志着编译器跳过所有类型检查,因此它在运行时发生。这意味着在运行时,您的动态将编译为对象。
事实证明,当您从显式.Where("Visible")
调用DynamicPublishedContentList
时,将调用.Where("Visible")
中的Umbraco.Web.PublishedContentExtensions
方法。但是,扩展方法不适用于动力学,因为C#RuntimeBinder无法使您访问扩展方法。当我们在.Where("Visible")
上调用CurrentPage.Site().Children
时,它没有看到扩展方法,而是调用了在TryInvokeMember
类上重写的DynamicPublishedContentList
方法。
这可能是您最简单的解决方案:
@helper CreateListItems(Umbraco.Web.Models.DynamicPublishedContentList collection)
至
@helper CreateListItems(dynamic collection)
或者,您可以使用类型更强的IPublishedContent。我喜欢这个,因为额外的智能帮助很大。
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
var root = Model.Content.AncestorOrSelf(1);
var selection = root.Children.Where(n => !n.GetPropertyValue<bool>("umbracoNaviHide")).ToList();
}
<div class="fleft menu_area">
<button class="btn btn-primary visible-xs" type="button" data- toggle="collapse" data-target="#mainMenu" aria-expanded="false" aria- controls="mainMenu"> <i class="glyphicon glyphicon-th-large"></i> Menu </button>
<div class="collapse navbar-collapse" id="mainMenu">
<ul class="nav navbar-nav">
@CreateListItems(selection)
</ul>
</div>
</div>
@helper CreateListItems(List<IPublishedContent> collection)
{
foreach (var item in collection)
{
if (item.Children.Any(n => !n.GetPropertyValue<bool>("umbracoNaviHide")))
{
<li class="menuOption dropdown @(item.IsAncestorOrSelf(Model.Content) ? "current" : null)" data-menu- id="@item.GetPropertyValue("menuOptionIdentifier")">
<a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" href="@item.Url">@item.Name</a>
<ul class="dropdown-menu">
@CreateListItems(item.Children.Where(n => !n.GetPropertyValue<bool>("umbracoNaviHide")).ToList())
</ul>
</li>
}
else
{
<li class="@(item.IsAncestorOrSelf(Model.Content) ? "current" : null)"><a href="@item.Url">@item.Name</a></li>
}
}
}
您可以使用
Model.Content
将当前页面作为IPublishedContent获取。关于c# - Umbraco动态“哪里”过滤器不一致地返回IQueryable或DynamicPublishedContentList,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32490735/