如何在模板化的razor委托中包含更多逻辑?

本文关键字:包含更 razor | 更新日期: 2023-09-27 17:50:31

参考Mr haked的扩展方法

public static class Helpers {
  public static HelperResult RenderSection(this WebPageBase webPage, 
      string name, Func<dynamic, HelperResult> defaultContents) {
    if (webPage.IsSectionDefined(name)) {
      return webPage.RenderSection(name);
    }
    return defaultContents(null);
  }
}

用法如下:

<footer>
  @this.RenderSection("Footer", @<span>This is the default!</span>)
</footer>

非常方便,但我想做的是,例如,在委托中包含一些业务逻辑,像这样:

<footer>
  @this.RenderSection("Footer", @<span>
               This @if (condition) {  
                        <label>is the</label> 
                      } else {  
                        <label> default!</label> 
                      } 
              </span>)
</footer>

但是无论我如何尝试更改扩展名,在查看页面时都会出现编译错误。

我怎样才能做到这一点?

如何在模板化的razor委托中包含更多逻辑?

David Fowler向我介绍了Razor的一个非常酷的功能,我没有意识到它已经在1.0中出现了,Templated Razor delegate。那是什么?我会让代码来说话。

@{
  Func<dynamic, object> b = @<strong>@item</strong>;
}
<span>This sentence is @b("In Bold").</span>

如果你有朋友会因为你使用粗体标签而不是强标签而"没有语义",那么这可能会派上用场。我正看着你戴米安咧着嘴笑呢。我是说,这两个词不都意味着强势吗?我跑题了。

注意生成的委托是一个Func。另外,@item参数是一个特殊的魔术参数。这些委托只允许有一个这样的形参,但模板可以根据需要多次调用该形参。

我展示的例子非常简单。我知道你在想什么。为什么不找个帮手呢?给我举个有用的例子。好的,你明白了!

假设我编写了这个非常酷的HTML辅助方法来生成任何类型的列表。

public static class RazorExtensions {
    public static HelperResult List<T>(this IEnumerable<T> items, 
      Func<T, HelperResult> template) {
        return new HelperResult(writer => {
            foreach (var item in items) {
                template(item).WriteTo(writer);
            }
        });
    }
}

这个List方法接受一个模板化的Razor委托,所以我们可以这样调用它。

@{
  var items = new[] { "one", "two", "three" };
}
<ul>
@items.List(@<li>@item)
</ul>

正如我前面提到的,注意这个方法的参数@

  • @item
  • 会自动转换为一个Func<动态的HelperResult>,这正是我们的方法所需要的。

    现在这个List方法是非常可重用的。让我们用它来生成一个漫画书表。

    @{
        var comics = new[] { 
            new ComicBook {Title = "Groo", Publisher = "Dark Horse Comics"},
            new ComicBook {Title = "Spiderman", Publisher = "Marvel"}
        };
    }
    <table>
    @comics.List(
      @<tr>
        <td>@item.Title
        <td>@item.Publisher
      </tr>)
    </table>
    

    这个特性最初是为了支持WebGrid helper方法而实现的,但我相信您会想到其他创造性的方法来利用它。