简体   繁体   中英

ASP.NET MVC Ajax (jQuery): generate code server-side?

I want to load some html data dynamically from the server (like a grid composed by lots f and ) using jQuery.

At the moment I load it like this:

$("#Ricerca_Div_ContenitoreRisultati table tbody").load("/Segnalazioni/CercaSegnalazioni/3");

and generate it like this:

    public ActionResult CercaSegnalazioni(int flag, string sort)
    {
        [..]

        XElement SegnalazioniTrovate = Models.Segnalazioni.Recupera(flag, sortVal);
        string ritorno = "";
        bool alterna = false;
        foreach (XElement segnalazione in SegnalazioniTrovate.Elements("dossier"))
        {
            ritorno += alterna? "<tr>" : "<tr class = \"alternata\">";
            ritorno += String.Format(@"
                <td><span style=""white-space: nowrap"">{0}</span></td>
                <td><span style=""white-space: nowrap"">{1}</span></td>
                <td style =""display : none"">{2}</td>
                <td><span style=""white-space: nowrap"">{3}</span></td>
                <td><span style=""white-space: nowrap"">{4}</span></td>
                <td><span style=""white-space: nowrap"">{5}</span></td>
            </tr>",
            (string)segnalazione.Element("NUM_DOSSIER") ?? "",
            (string)segnalazione.Element("ANAG_RAGSOC_CGN") ?? "",
            (string)segnalazione.Element("ID_RIFATT_SEGN0") ?? "",
            Tools.DecodificaStatus(int.Parse((string)segnalazione.Element("FLG_STATUS") ?? "")),
            Tools.RmuoviTime((string)segnalazione.Element("DT_ACCADIMENTO")?? ""),
            (string)segnalazione.Element("COD_RAMO_LUNA") ?? ""
            );

            alterna = !alterna;
        }
        return Content(ritorno);
    }

Or, simply put, I make up the HTML code server side with a very messy code I don't like and return it back so that it is ready to be used client-side.

Any better / cleaner solution? Thanks

There's different ways of doing this, and although none of them end up looking perfectly clean, the one that works best for me is to do the HTML construction on the client side. The server can return an object that works well in javascript (let's say, List<Segnalazione> ) and then the client-side handler does things like:

$(list).each(function() {
  var tr = $('<tr />').append(
    $('<td />').css('white-space', 'nowrap').text(this.NUM_DOSSIER)
  ).append(
    $('<td />').css('white-space', 'nowrap').text(this.ANAG_RAGSOC_CGN)
  )

  $("#Ricerca_Div_ContenitoreRisultati table tbody").append(tr);
});

Obviously, I'm oversimplying your output, but hopefully that gives you the idea.

If nothing else, doing it in jquery gives you the automatic escaping of values within the 'text', 'attr', and 'css' methods rather than the HttpUtility.HtmlEncode, AttributeEncode methods that would clutter up your output in C#

The cleaner solution will be creating separate View and using more CSS:

UPDATED:

In case of Request.IsAjaxRequest() use PartialView:

Controller:

public ActionResult CercaSegnalazioni(int flag, string sort)
{
    [..]

    XElement SegnalazioniTrovate = Models.Segnalazioni.Recupera(flag, sortVal);

    return PartialView("YourPartialView", SegnalazioniTrovate);
}

YourPartialView.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<XElement>" %>

<% bool alterna = false; %>
<table id="yourTableId">
    <% foreach (XElement segnalazione in SegnalazioniTrovate.Elements("dossier")) { %>
    <tr class="<%= alterna ? "alternata" : "" %>">
    <% alterna = !alterna; %>
        <td>
            <span><%= (string)segnalazione.Element("NUM_DOSSIER") ?? "" %></span>
        </td>
        <td>
            <span><%= (string)segnalazione.Element("ANAG_RAGSOC_CGN") ?? "" %></span>
        </td>
        <td class="nodisplay">
            <%= (string)segnalazione.Element("ID_RIFATT_SEGN0") ?? "" %>
        </td>
        <td>
            <span><%= Tools.DecodificaStatus(int.Parse((string)segnalazione.Element("FLG_STATUS") ?? "")) %></span>
        </td>
        <td>
            <span><%= Tools.RmuoviTime((string)segnalazione.Element("DT_ACCADIMENTO")?? "") %></span>
        </td>
        <td>
            <span><%= (string)segnalazione.Element("COD_RAMO_LUNA") ?? "" %></span>
        </td>
    </tr>
    <% } %>
</table>

CSS:

table#yourTableId td span {
    white-space: nowrap
}

.nodisplay {
    display : none
}

Your best bet is probably to de-couple the presentation from the data. This would mean avoiding having any presentation code (ie. HTML generation) in your controller.

There are 2 ways to handle this...

Nested Partial Views

Partial Views can render... other partial views. Consider something like this...

<body> Page
-- <div> Partial View "parent" (does a RenderPartial of these:)
---- <div> Partial View "child" (piece 1) </div>
---- <div> Partial View "child" (piece 2) </div>

The parent partial view simply contains RenderPartials for the children. In addition, each patial view can end up having it's own URL (/controller/parent/, /controller/child-1/, etc.). In jQuery whenever you trap an event that needs to update the UI, you can simply ajax.load the piece you need and plug it into the div.

JSON -> jQuery Render

The other way is you forgo the server creating any presentation code, and you simply have an API that returns JSON. jQuery then accepts the incoming data objects and figures out what to do with them. Depending on the complexity of what needs to be rendered on the client side, this could be easier. This has the advantage of also allowing the same server-side code to be re-used in other ways. The downside is the content won't be indexed by search engines.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM