14

我正在尝试为篮子项目列表制作自定义模板。我需要一些不同的模板,因为我有不同的显示项目的方式,具体取决于它是在网页上还是在邮件中。现在我的问题是,当我使用默认名称时,它可以完美地工作。

@Html.DisplayFor(b => b.Items)

但是当我尝试添加模板名称时,我期望我的模板需要是列表类型 IEnumerable 而不是 BasketItem。

@Html.DisplayFor(i => basket.Items, "CustomerItemBaseList")

任何我的错误所在的想法,或者为什么它不可能的想法都值得赞赏。谢谢。

4

4 回答 4

22

不幸的是,这是模板化助手的限制。如果您为集合属性指定模板名称,则模板不再自动应用于集合的每个项目。可能的解决方法:

@for (int i = 0; i < Model.Items.Length; i++)
{
    @Html.DisplayFor(x => x.Items[i], "CustomerItemBaseList")
}
于 2011-04-29T17:24:20.107 回答
2

这是个好主意,达林。不过我很懒,所以我想更进一步,做一个真正的帮手来包装它。我还取出了 lambda 表达式以针对我的情况对其进行简化,但您可以轻松地重新添加该功能。

    public static class DisplayTextListExtension
{
    public static MvcHtmlString DisplayForList<TModel>(this HtmlHelper<TModel> html, IEnumerable<string> model, string templateName)
    {
        var tempResult = new StringBuilder();

        foreach (var item in model)
        {
            tempResult.Append(html.DisplayFor(m => item, templateName));
        }

        return MvcHtmlString.Create(tempResult.ToString());
    }
}

那么实际的用法是这样的:

                                @Html.DisplayForList(Model.Organizations, "infoBtn")
于 2013-11-01T21:35:30.757 回答
1

我喜欢 Dan 的回答,但稍作调整,因为它适用于任何 IEnumerable:

using System.Collections;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace YourProject.Whatever
{
    public static class DisplayExtensions
    {
        public static MvcHtmlString DisplayForIEnumerable<TModel>(this HtmlHelper<TModel> html, IEnumerable model, string templateName)
        {
            var tempResult = new StringBuilder();

            foreach (var item in model)
            {
                var item1 = item;
                tempResult.Append(html.DisplayFor(m => item1, templateName));
            }

            return MvcHtmlString.Create(tempResult.ToString());
        }
    }
}

而且当然:

@Html.DisplayForIEnumerable(Model.Organizations, "NameOfYourDisplayTemplate")
于 2015-05-10T03:05:45.003 回答
1

我建议使用该方法的additionalViewData参数,对异构对象列表(即 BasketItem 子类)更有用的另一种解决方案DisplayFor,例如:

@DisplayFor(b=>b.Items, new { layout="row" })

通过这种方式,助手可以正常工作IEnumerable<T>,为每个项目(T 的子类)调用相关的DisplayTemplate ,并将字典中AdditionalViewData值传递给它。ViewData

模板可以为不同的布局值输出不同的代码。

在上面的示例中,名为 View\Shared\DisplayTemplates\ BasketItem的模板(或子类的名称)应如下所示:

@model MyProject.BasketItem // or BasketItem subclass
@{ 
    string layout = ViewData["layout"] as string ?? "default";

    switch(layout)
    {
        case "row":
            <div class="row">
            ...
            </div>
        break;
        // other layouts
        ...
        default: // strongly recommended a default case
            <div class="default-view>
            ...
            </div>
        break;
    }
}

强烈建议始终提供默认代码。

我希望这个建议能有所帮助。

于 2016-02-04T16:36:06.500 回答