Skip to content

Instantly share code, notes, and snippets.

@tuespetre
Last active August 29, 2015 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tuespetre/157a1e5eb5fd820039d8 to your computer and use it in GitHub Desktop.
Save tuespetre/157a1e5eb5fd820039d8 to your computer and use it in GitHub Desktop.

Sample Usage

Example from unrender.js:

 <tbody>
   @helper rows(YourItemType item)
   {
     <tr ng-repeat-start="item in Model.Items">
       <td ng-bind="item.Name" data-unrender="unbind">
         @item.Name
       </td>
       <td ng-bind="item.NumberInStock" data-unrender="unbind">
         @item.NumberInStock
       </td>
       <td ng-bind="item.PricePerEach" data-unrender="unbind">
         @item.PricePerEach
       </td>
     </tr>
     <tr ng-repeat-end data-unrender="unloop">
       <td colspan="3" ng-bind="item.Description" data-unrender="unbind">
         @item.Description
       </td>
     </tr>
   }
   @helper empty()
   {
     <tr ng-if="!Model.Items.length">
       <td colspan="3">
         Sorry, no items at this time.
       </td>
     </tr>
   }
   @* 
     The 'if' block has been placed first so that
     the 'unloop' transformation doesn't wipe out
     the <script> from the 'if' block.
   *@
   @Html.If(!Model.Items.Any(), empty)
   @Html.Foreach(Model.Items, rows)
 </tbody>

Caveats

The implementation is kind of quick and naive. When using Foreach, if your collection is null or empty, it will create a dummy object for whatever type you passed in, so make sure all of the expressions in your template are fail-safe with a dummy object (having automated tests for your web app wouldn't hurt, either.) Take similar precautions when referencing your model within an if/else/switch/case block simulated with If.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.WebPages;
public static class IsomorphicRazorExtensions
{
public static HelperResult Foreach<T>(this HtmlHelper helper, IEnumerable<T> items, Func<T, HelperResult> template)
where T : class, new()
{
if (items == null || !items.Any())
{
return new HelperResult(writer =>
{
var wrapper = new TagBuilder("script");
wrapper.Attributes.Add("type", "text/html");
wrapper.Attributes.Add("data-unrender", "unpack");
writer.Write(wrapper.ToString(TagRenderMode.StartTag));
template(new T()).WriteTo(writer);
writer.Write(wrapper.ToString(TagRenderMode.EndTag));
});
}
else
{
return new HelperResult(writer =>
{
foreach (var item in items)
{
template(item).WriteTo(writer);
}
});
}
}
public static HelperResult If(this HtmlHelper helper, bool condition, Func<HelperResult> template)
{
if (condition)
{
return new HelperResult(writer =>
{
template().WriteTo(writer);
});
}
else
{
return new HelperResult(writer =>
{
var wrapper = new TagBuilder("script");
wrapper.Attributes.Add("type", "text/html");
wrapper.Attributes.Add("data-unrender", "unpack");
writer.Write(wrapper.ToString(TagRenderMode.StartTag));
template().WriteTo(writer);
writer.Write(wrapper.ToString(TagRenderMode.EndTag));
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment