【问题标题】:Razor - how to render content into a variableRazor - 如何将内容渲染到变量中
【发布时间】:2010-11-28 09:42:28
【问题描述】:

Razor中如何将一段Html渲染成一个变量? 在 Spark 中,我曾经编写过以下代码:

<content var="t">
    <a class="tab" href="">Tab name</a>
</content>

<content var="tc">
    <div class="tabcontent">
        <p>Here goes tab content</p>
    </div>
</content>

!{tabs(t, tc)}

两个变量被传递给一个宏,该宏将所有内容都很好地包装到标签页中。

在 Razor 中执行相同操作的最佳方法是什么?

更新:我想我明白了..

在 Razor 中,@&lt;text&gt;...&lt;/text&gt; 构造可以由用户生成 lambda 表达式,以后可以重用,这相当于将一段 HTML 分配给变量。上面的例子可以通过以下方式实现:

Func<int, object> t =
    @<text>
        <a class="tab" href="">Tab name</a>
    </text>;

Func<int, object> tc =
    @<text>
        <div class="tabcontent">
            <p>Here goes tab content</p>
        </div>
    </text>;


@tabs(t(0), tc(0))

我只是不知道如何编写无参数 lambda (Func&lt;object&gt;)。上面两个 lambda 中的 int 参数是一个虚拟参数。 Razor 似乎需要一个参数(并且已经创建了一个变量“item”来在表达式中表示它)。

【问题讨论】:

    标签: asp.net-mvc-3 razor


    【解决方案1】:

    基本上,OP 已经回答了这个问题,您可以执行以下操作:

    @{
       Func<dynamic, object> a = @<text>
           Some Text        
       </text>;
       @a(new object())
    }    
    

    如果文本仅用于单行,您甚至可以使用“@:”运算符,只需记住在下一行有一个分号(或者如果它需要任何右括号或括号),如下例所示:

    @{
       Func<dynamic, object> a = @: Some Text
       ;    
       @a(new object())
    }
    

    但是,如果您愿意,您可以直接将其捕获为字符串

    @{
        string a = ((Func<dynamic, object>)(@<text>
                        Some Text
                    </text>))("").ToString();
        @a //Output directly as a string        
    }
    

    你甚至可以将它封装在一个函数中:

    @functions{
         public string ToString(Func<dynamic, object> input)
         {
              return input("").ToString();
         }
    }
    
    @{
        string a = ToString(@<text>
                        Some Text
                   </text>);
        @a //Output directly as a string        
     }
    

    【讨论】:

      【解决方案2】:

      万一其他人发现这篇文章(就像我一样),安迪的更新就快到了。除了给出的示例之外,在给出的示例中访问“int”所需要做的就是参考@item。在@&lt;text&gt;&lt;/text&gt; 块中,变量item 包含调用它的模型。

      这是一个如何使用它的示例:

      @model PageData
      
      @{
          Func<Customer, object> sayHi = 
              @<text>
                   <li>Hello @(item.FirstName)!</li>
               </text>;
      }
      
      <ul>
          @foreach(var customer in Model.Customers)
          {
              sayHi(customer);
          }
      </ul>
      

      在大多数情况下,您可能应该使用局部视图而不是这样的函数。但在极少数情况下(例如在使用 RazorEngine 库时)无法进行局部视图时,这是可行的。

      【讨论】:

        【解决方案3】:

        也许你可以使用 HtmlString?我不认为我很喜欢这个,但这是我想尝试的准确翻译你所拥有的......

        @{
            var t = new HtmlString("<a class='tab' href=''>Tab name</a>");
            var tc = new HtmlString("<div class='tabcontent'><p>Here goes tab content</p></div>");
        }
        @tabs(t, tc)
        

        所以...我不知道您的 Spark 宏是什么样的,但这似乎是在 Razor 中使用助手的机会。你可能有类似的东西:

        @helper Tabs(string tabName, string tabContent)
        {
            <!-- some wrapper code -->   
            <a class="tab" href="">@(tabName)</a>
            <!-- some more wrapper code -->
            <div class="tabcontent">
                <p>@(tabContent)</p>
            </div>
            <!-- still more wrapper code -->
        }
        

        然后你在你的页面中这样调用它:

        @Tabs("Tab Name", "Here goes tab content")
        

        【讨论】:

        • 谢谢,我认为我真正需要的是内联辅助语法。我不知道这在 Razor 中是否可用。解决方案是声明一个显式帮助器,它可以被调用并将结果分配给一个变量。
        • 我在上面的评论中错了。语法可用,不需要显式帮助器。可以改用 Lambda 表达式。请参阅我更新的问题。
        【解决方案4】:

        如果您的 Razor 视图中有 IHtmlContentBuilder,则可以使用这些扩展。

            public static IHtmlContentBuilder AppendRazor(this IHtmlContentBuilder htmlContentBuilder, Func<IHtmlContent, dynamic> lamda)
            {
                var html = lamda(null);
                return htmlContentBuilder.AppendHtml(html);
            }
        
            public static IHtmlContentBuilder AppendRazor<T>(this IHtmlContentBuilder htmlContentBuilder, Func<T, IHtmlContent> lamda, T model)
            {
                var html = lamda(model);
                return htmlContentBuilder.AppendHtml(html);
            }
        

        用法

        @{
            HtmlContentBuilder contentBuilder = new HtmlContentBuilder();
            contentBuilder.AppendRazor(@<text><p>Hello @Model.Name<p></text>);
            contentBuilder.AppendRazor(@<text><p>Hello @item.CustomerName<p></text>, customer);
        }
        <div>
             @contentBuilder
        </div>
        

        【讨论】:

          猜你喜欢
          • 2015-12-21
          • 2018-01-25
          • 2020-08-26
          • 2013-06-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多