Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid duplicate formatting between server-side Razor view and client-side jQuery template

I have a search results page where I output a list of items formatted in a particular way using a MVC Razor view.

@for (int i = 0; i < group.Count(); i++) {
  <div class="result">
    <div class="ordinal">@((i+1).ToString()).</div>
    <div class="detail"><p>@group.ElementAt(i).Name</p></div>
  </div>
}

The client can further filter those results using jQuery AJAX to retrive a new dataset as JSON and jQuery templates to render the resultset in place of the original. This is the jQuery Template:

<script id="resultTemplate" type="text/x-jquery-tmpl">
  {{each(i, result) results}}
    <div class="result">
      <div class="ordinal">${i+1}.</div>
      <div class="detail"><p>${name}</p></div>
    </div>
  {{/each}}
</script>

which is bound after AJAX call:

var result = $("#resultTemplate").tmpl({ results: data });
$("#resultsColumn").empty().append(result);

Note how I had to duplicate the HTML formatting for a search result in both server-side Razor code and client-side jQuery code. I'd like to have just one version of the data bound template to reduce the chance of mismatches when I have to make changes.

Reading Stephen Walter's Intro to jQuery Templates he's hinting at "better together" integration when using jQuery templates with ASP.NET MVC so I was wondering if there's a facility that addresses the above scenario.

Thanks.

like image 395
stefann Avatar asked Nov 13 '22 18:11

stefann


1 Answers

I guess you could use the @helper syntax to avoid some of the duplicated markup.

@helper Result(string ordinal, string name) {
    <div class="result">
        <div class="ordinal">@ordinal.</div>
        <div class="detail"><p>@name</p></div>
    </div>
}

Then use the helper for both the Razor view

@for (int i = 0; i < group.Count(); i++) {
    @Result((i+1).ToString(), group.ElementAt(i).Name)
}

and the jQuery template

<script id="resultTemplate" type="text/x-jquery-tmpl">
    {{each(i, result) results}}
        @Result("${i+1}", "${name}")
    {{/each}}
</script>

That's assuming your jQuery template resides in the Razor view itself.

On the downside, you have to convert every argument to string before passing them to the helper. And, for some reason, passing "${i+1}" to the helper feels plain wrong.

I'm not sure yet I would use that kind of approach in production, but I guess it depends on the complexity of the markup involved.

like image 117
Bryan Menard Avatar answered Dec 04 '22 08:12

Bryan Menard