将Ajax接收到的数据在强类型视图中呈现

3
在我的ASP.NET MVC应用程序中,我有一个Ajax调用,它从服务器读取记录并应在客户端显示。视图文件是强类型的,因此我拥有页面上的所有元素。
我该如何在页面上呈现这些接收到的数据?请注意,我必须使用Ajax显示不同的数据。这是一种单页面应用程序(SPA),但我真的不想使用第三方库,除非它们具有真正的优势。
操作方法的返回值如下所示:
var data = repoH.GetAll().Where(....).FirstOrDefault();
return Json(data);

还有Ajax调用:

$(document).ready(function () {
    $.ajax({
        url: '@Url.Action("action", "controller")',
        method: 'post',
        success: function (result) {
            debugger;
        }
    });
});

视图长这样:
<form id="formId">
   @Html.HiddenFor(x => x.Id)
   <div class="form-group form-inline col-xs-12">
      <div class="col-xs-6">
         @Html.LabelFor(x => x.fieldA, new { @class = "control-label col-xs-6" })
         @Html.EditorFor(x => x.fieldA)
      </div>......
   </div>

使用一些按钮和自定义的Ajax调用,我必须以这种方式实现整个CRUD操作!

欢迎任何建议!如果我有任何错误,请告诉我,这个应用程序已经改变了几次,我真的很困惑!


你的视图是什么样子? - noobed
1
如果您希望以强类型方式进行更新,我会从控制器返回部分视图而不是json。 - Dmitry Pavliv
在ajax调用的成功部分,只需解析结果并将其作为html附加到页面上的某个目标元素中,以便数据归属。 - Daniel Dušek
我在页面上还有其他元素,所以我认为返回部分视图不会起作用。@dee,我该怎么解析它?我想避免重复,需要使用foreach吗? - Akbari
还有一件事,它们并不在同一个地方!我必须在它们之间放置其他元素。我还有其他解决方案吗?因为即使这样可以工作,我最终会得到很多部分视图。 - Akbari
显示剩余4条评论
2个回答

2

我不确定你是否有可能在服务器端渲染此内容,但是是的。

首先,这个 ... return Json(data); 不是真正的 asp.net mvc 方法,因为你没有返回视图。

假设你有这样一个东西。

var databaseModel = repoH.GetAll().Where(....).FirstOrDefault();

/* optionally, but best practice var viewModel = map databaseModel to some viewModel */ 

然后使用一种方法将您的viewModel渲染为字符串。
  // this will be in a RenderingHelper class 
  public static string RenderViewToString(ControllerContext context, string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = context.RouteData.GetRequiredString("action");

            ViewDataDictionary viewData = new ViewDataDictionary(model);

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
                ViewContext viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw);
                viewResult.View.Render(viewContext, sw);

                return sw.GetStringBuilder().ToString();
            }
        }

因此,您需要创建一个部分,接受您的viewModel(databaseModel),然后存储已呈现的html:

string renderedHtml = RenderingHelper.RenderViewToString(this.ControllerContext, "~/Views/MyController/MyPartial", viewModel);

您可以返回一个 Json,其中包含渲染后的 HTML 和其它您想要的数据 { RenderedHtml = renderedHtml, SomeData = someData }

您将在响应中收到渲染后的 HTML:

success: function (response) {
            // test if you have response.RenderedHtml
            // and then override your container html with what you rendered on the server            $('#your_container_to_render_data_on_the_page').html(response.RenderedHtml);
        }

您可以创建一个数据库模型(viewModel),然后呈现相应的局部视图(server-side),最后将呈现的HTML返回给客户端(client-side)。

我没有看到其他方法。


Angular JS 有意义吗?我不确定它是否与这种类型的问题相关。 - Akbari
你没有说明你是否有Angular。有了Angular,就有另一种方法:Web API。你总是从服务器返回数据,并在客户端渲染视图。 - Razvan Dumitru
我没有Angular。我只是问一下,因为我不熟悉它,所以有没有必要学习它。还有一个问题!学习Angular和Web API需要多长时间?我正在进行一个项目,你建议我学习它们吗?如果学习时间少于20小时,我可以应付。 - Akbari
1
这是一种完全不同的方法。如果你正在进行一个项目,最好的方法是坚持使用那种技术。如果你所有的视图都是用 Razor(asp.net)编写的,你只需要花费大约10分钟的时间将它们从 Razor 移动到 Angular(用于渲染的客户端模板)。 - Razvan Dumitru
1
你需要大约3个小时来进行设置,另外还需要1个小时来进行表单验证等操作。这是在你熟悉框架之后的情况。 - Razvan Dumitru
1
Angular使用客户端路由。混合路由(客户端和服务器端)难以管理且相当奇怪。因此,无论您选择混合还是仅保留客户端路由,这都需要花费很多时间。 - Razvan Dumitru

1
例如,您有一个返回json的操作:
[HttpGet]
public ActionResult GetValidConnectionTypes(string code)
{
    SelectList validConnectionTypes = GetValidConnectionTypes(code);
    return Json(validConnectionTypes, JsonRequestBehavior.AllowGet);
}

在视图中,您有一个JavaScript函数,通过ajax调用此操作,并将结果作为data接收:

function loadValidConnectionTypes(code) {
    $deferred = $.Deferred();

    $.ajax({
        url: getValidConnectionTypesUrl,
        data: { code: code },
        dataType: "json",
        type: "GET"
    })
    .done(function (data) {
        var items = "";
        $.each(data, function (i, item) {
            items += "<option value=\"" + item.Value + "\">" + item.Text + "</option>";
        });

        var selectItem = $("#ConnectionType");
        selectItem.html(items);

        $deferred.resolve();
    })
    .fail(function (r, s, e) {
        $deferred.reject();
    });

    return $deferred.promise();
} 

然后在done部分,只需通过创建一个类似于示例中的html(<option></option>),并将其附加到页面上(selectItem.html(items))来解析data。希望对你有帮助。


谢谢,但我有很多元素,不只是其中一个。而且它们来自不同的类型。 - Akbari
好的,这只是一个“一般情况下”可以完成的示例。或者您也可以从操作中返回完整的HTML,而不是JSON。意味着创建部分视图,并将其作为HTML从操作返回。 - Daniel Dušek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接