【问题标题】:How to mix HTML and C# Code in MVC3 with Razor?如何将 MVC3 中的 HTML 和 C# 代码与 Razor 混合使用?
【发布时间】:2011-06-12 04:31:39
【问题描述】:

我正在尝试显示应切换类以进行样式设置的项目列表。这个想法是创建一个 foreach 循环,循环遍历模型中的所有 myObj

我尝试了以下代码但不起作用(因为我做错了)

@{ int i = 2;
   foreach(var myObj in Model)
   {
        if (i % 2 == 0)
        {
            <div class="class1">
        }
        else
        {
            <div class="class2">
        }
        Html.Partial(...);
        </div>
         i += 1;
   }     
}

实现此目的的正确方法是什么?

更新
我还尝试了以下代码,虽然可以编译,但不会在其中呈现任何 HTML 代码(而且我确信 Model 中有对象)。

@{ int i = 2;
   foreach(var myObj in Model)
   {
        if (i % 2 == 0)
        {
            @:<div class="class1">
        }
        else
        {
            @:<div class="class2">
        }
        Html.Partial(...);
        @:</div>

        i += 1;
   }

}

这是被调用的部分类

<div class="class">
    <div class="class2">
        @if (string.IsNullOrEmpty(var))
        {
            @var2
        }
        else
        {
            @var
        }
    </div>
    <div class="class3">
        @var3
    </div>
</div>
<div class="class4">
    <p>var4</p>
    <ul class="class5">
        <li>element1</li>
        <li>element2</li>
    </ul>
</div>

很抱歉,我无法发布实际名称和变量。

【问题讨论】:

  • 您能否更具体地说明一下它是如何不起作用的?你得到输出了吗?你有例外吗?
  • 更新:我们可以看到部分视图和调用它吗?

标签: asp.net-mvc-3 razor


【解决方案1】:

让我们从改进您的代码开始。

  • 改进步骤 1:

    @foreach(var myObj in Model.Select((model, index) => new { model, index }))
    {
        <div class="class@(myObj.index % 2 == 0 ? "1" : "2")">
            @Html.Partial("_Foo", myObj.model)
        </div>
    }
    
  • 改进第 2 步(为类使用自定义 HTML 帮助器):

    @foreach(var myObj in Model.Select((model, index) => new { model, index }))
    {
        <div class="@Html.MyClass(myObj.index)">
            @Html.Partial("_Foo", myObj.model)
        </div>
    }
    

    MyClass 的定义如下:

    public static string MyClass(this HtmlHelper html, int index)
    {
        return (index % 2 == 0) ? "class1" : "class2";
    }
    
  • 最先进的改进步骤 3(使用 Templated Razor Delegates):

    @Model.List(
        @<div class="@item.MyClass">
            @Html.Partial("_Foo", @item.Model)
        </div>
    )
    

    List 扩展方法如下所示:

    public class ModelHolder<T>
    {
        public T Model { get; set; }
        public string MyClass { get; set; }
    }
    
    public static class RazorExtensions
    {
        public static HelperResult List<T>(
            this IEnumerable<T> items,
            Func<ModelHolder<T>, HelperResult> template
        )
        {
            return new HelperResult(writer =>
            {
                foreach (var item in items.Select((model, index) => new { model, index }))
                {
                    var myClass = item.index % 2 == 0 ? "class1" : "class2";
                    template(new ModelHolder<T> { Model = item.model, MyClass = myClass }).WriteTo(writer);
                }
            });
        }
    }
    

我投票支持第 3 号改进,它比原来的 foreach 循环更好、更简洁。

【讨论】:

  • 我进行了第 1 项改进,它奏效了。为了将来参考,我没有测试其余部分。
  • 我相信回顾和咨询旧问题总是好的......当时这个答案看起来很复杂,我什至没有尝试其他改进,现在一切似乎都很明显......再次感谢达林,这是一个非常好的答案。
【解决方案2】:

您需要在带有非格式良好标签的行前加上 @: 以防止 Razor 尝试解析标签。
Details

【讨论】:

    【解决方案3】:

    您可能确定某些模型中有对象 - 但不是您的模型 :) 以下直接从您的代码派生的示例代码可以正常工作:

    @{ int i = 2; string[] list = new string[] {"a","b","c","d"}; foreach(var myObj in list) { if (i % 2 == 0){ @:<div class="class1"> } else { @:<div class="class2"> } //Html.Partial(...); @:</div> i += 1; } }

    【讨论】:

      【解决方案4】:

      您需要编写@Html.Partial(...) 以将结果呈现到页面。

      调用Html.Partial 会返回带有局部视图的HelperResult,但实际上并不渲染它。

      【讨论】:

        猜你喜欢
        • 2011-09-18
        • 1970-01-01
        • 2011-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多