views:

78

answers:

1

I have the following code to generate a list and will allow developers to customize the output if needed.

<% Html.List<MyList>(item => item.Property).Value(item => return "<div>" + item.Property + "<br/>" + item.AnotherProperty + "</div>").Render() %>

This is not ideal, how can I allow the developers to add the html similar to other controls.

<% Html.List<MyList>(item => item.Property).Value(item => %> <div><%=item.Property%><br/><%=item.AnotherProperty%></div><%).Render() %>

This way is much cleaner and standard with the rest of mvc.

+2  A: 

The <%=%> tags are simply a shortcut for Response.Write. If you think about it, the lambda expression is simply allowing you to defer execution of the Response.Write code until the appropriate time.

So, the important part is to call Response.Write to build your list, and when it’s time to inject the custom template, I just execute the lambda which does a Response.Write to inject the template.

Here is some example code to help illustrate:

public class TableBuilder
{
    private Action<int> _template;

    public TableBuilder Template(Action<int> template)
    {
        _template = template;
        return this;
    }

    public void Render()
    {
        var r = HttpContext.Current.Response;

        r.Write("<table>");

        for(int i=0; i<10; ++i)
        {
            r.Write("<tr><td>");
            if(_template != null)
            {
                _template(i);
            }
            r.Write("</td></tr>");
        }

        r.Write("</table>");
    }
}

Then, to use the Helper, do the following:

<body>
    <div>
    <% Html.TableBuilder().Template(i => { %>

                                          <%= i %>: I'm a template

                        <% }).Render(); %>
    </div>
</body>

This is a neat trick!

Page Brooks
+1 for a great answer, even though I think the final syntax is uglier than string concatenation
Gabe Moothart
I agree, it's pretty darn ugly!
Page Brooks