gpt4 book ai didi

How to refresh data displayed in ViewComponent's default View : ASP.NET MVC Core(如何刷新ViewComponent的默认视图中显示的数据:ASP.NET MVC Core)

转载 作者:bug小助手 更新时间:2023-10-25 21:19:01 25 4
gpt4 key购买 nike



I have a razor view that is divided into two columns. The column on the left contains a list of bootstrap list-group-items ( job cards). On the right is a larger column to display the full details of the active job card. The right column is simply a viewcomponent which takes as parameter a job entity and render it details on the default view.

我有一个被分成两列的剃须刀视图。左侧的列包含引导列表-组-项目(作业卡)的列表。右侧是一个较大的列,用于显示活动工单的完整详细信息。右列只是一个视图组件,它接受一个作业实体作为参数,并在默认视图上呈现它的详细信息。


Here is my main view

以下是我的主要观点


@model IEnumerable<JobListing>
<div class=" d-flex justify-content-center col-12 row my-3 mx-0 p-0 row position-relative">

<!--collection of Listing cards -->
<div style=" " class=" d-flex justify-content-start col-sm-12 col-lg-5 col-xl-4 m-0 p-0 pe-4">
<div id="jobList" class="list-group col-12 m-0 p-0 border-0 ">


@foreach (var listing in Model)
{


<div id="listing-@count" class="list-group-item list-group-item-action " data-bs-toggle="list" href="#listing-@count">
<!-- Listing Card -->
</div>

count++;
}
</div>
</div>


<!--Job Details-->
<div style="" class="s p-1">
<div id="jobDetail" class=" h-auto border border-1 border-primary rounded rounded-3 align-items-start ">

@await Component.InvokeAsync("JobDetail", new {joblisting = Model.ElementAt(0)})
</div>
</div>

</div>

Initially the first job in the list is loaded by the viewcomponent. Now, I have added click eventListener to each card to capture when it's selected and then pass a serialized version of the active joblisting object to this ajax method LoadJobDetail(...)

最初,列表中的第一个作业由视图组件加载。现在,我已经向每个卡片添加了Click EventListener,以便在它被选中时捕获它,然后将活动的joblisting对象的序列化版本传递给这个AJAX方法LoadJobDetail(...)


 <script>
const divItems = document.querySelectorAll('.list-group-item');

divItems.forEach(function (div) {
div.addEventListener('click', function () {
var job = this.getAttribute('data-job');

LoadJobDetail(job);
});
});

function LoadJobDetail(jobListing) {
$.ajax({
type: "GET",
url: "customer/Home/LoadJobDetail",
data: { job: JSON.stringify(jobListing) },
success: function (response) {
// Refresh viewcomponent data
},
error: function (error) {
console.log("operation failed...", error);
}

});
}

</script>

The ajax method calls this action method which in turn invokes the view component and pass the job...

AJAX方法调用此操作方法,该操作方法又调用视图组件并传递作业...


[HttpGet]
public IActionResult LoadJobDetail(string job)
{
// Convert string to joblisting
JobListing jobDetail = JsonConvert.DeserializeObject<JobListing>(job);

if (jobDetail != null)
{
var result = ViewComponent("JobDetail", new { jobListing = jobDetail });
return Json(new { response = result, success = true, message = "Job detail successfully loaded" });
}
else
{
return Json(new { response = "", success = false, message = "could not load the selected job listing" });
}
}

And here is my ViewComponent class

这是我的ViewComponent类


 public async Task<IViewComponentResult> InvokeAsync(JobListing jobListing)
{

// return the view
return View(jobListing);
}

The view for my ViewComponent expects as model a JobListing object. So far all the code till the step of invoking the ViewComponent works fine. I added a breakpoint on the Default.cshtml for the ViewComponent and the properties are being set. But the data in View never refreshes. Any help on how to display the details for selected job? Perhaps am using the wrong approach. I've thought of using partial view instead but doesn't sound reasonable.

My ViewComponent的视图需要建模一个JobListing对象。到目前为止,直到调用ViewComponent的步骤之前的所有代码都工作正常。我为ViewComponent在Default.cshtml上添加了断点,并且正在设置属性。但View中的数据永远不会刷新。关于如何显示所选作业的详细信息,有什么帮助吗?也许我使用了错误的方法。我想用局部视图来代替,但听起来不太合理。


更多回答
优秀答案推荐

Based on @Stilgar suggestion to use partial view, I also found a similar suggestion on Microsoft developers forum and decided to try that and it works. Whether it's the best approach I can't tell as am a beginner.

基于@Stilgar使用部分视图的建议,我在微软开发者论坛上也找到了类似的建议,并决定尝试一下,它奏效了。作为一个初学者,我不知道这是不是最好的方法。


I created a partial view with same code and model as that in my Default.cshtml for the previous ViewComponent. Then modified the action method to return the partial view with it's model like so

我创建了一个部分视图,其代码和模型与前一个ViewComponent的Default.cshtml中的代码和模型相同。然后修改操作方法以返回带有其模型的局部视图,如下所示


[HttpGet]
public IActionResult LoadJobDetail(string job)
{
// Convert string to joblisting
JobListing jobDetail = JsonConvert.DeserializeObject<JobListing>(job);

return PartialView("_JobDetailsPartial", jobDetail);
}

And then modified the ajax call to load the result inside the jobDetailContainer div

然后修改了AJAX调用,将结果加载到jobDetailContainer div中


function LoadJobDetail(jobListing) {

$.ajax({
type: "GET",
url: "customer/Home/LoadJobDetail",
data: { job: JSON.stringify(jobListing) },
success: function (response) {

$('#jobDetail').html(response);
console.log(response);
},
error: function (error) {
console.log("operation failed...", error);
}

});

Everything else remain the same. Don't know if it's the right approach but it looks cleaner than trying to convert a viewComponentResult into html code.

其他一切都保持不变。我不知道这是不是正确的方法,但它看起来比试图将viewComponentResult转换成html代码更干净。



I think the problem is that the result you are assigning to the response is nothing like a string. It's some form of ActionResult. You probably want to return it directly and use the string as HTML rather than JSON, I don't see the use for the JSON here at all. In addition it seems that you can use the simpler partial views here as you don't do anything in the ViewComponent Invoke method. Finally this whole thing is super weird since you are sending the data from the client to the server just to produce the HTML but you already have the data on the client and you can produce the HTML there by replacing a bunch of HTML elements.

我认为问题在于您分配给响应的结果与字符串完全不同。它是ActionResult的某种形式。您可能希望直接返回它,并将该字符串用作HTML而不是JSON,我根本看不出JSON在这里有什么用处。此外,您似乎可以在这里使用更简单的局部视图,因为您不需要在ViewComponent Invoke方法中执行任何操作。最后,这整件事非常奇怪,因为您将数据从客户端发送到服务器,只是为了生成HTML,但是您已经在客户端上拥有数据,并且您可以通过替换一组HTML元素在客户端生成HTML。



To convert a ViewComponentResult into an HTML string and include it in a JSON response, you can render the ViewComponent to a string and then send that string as part of your JSON response. Here's how you can do it:

要将ViewComponentResult转换为HTML字符串并将其包含在JSON响应中,可以将ViewComponent呈现为字符串,然后将该字符串作为JSON响应的一部分发送。以下是你如何做到这一点:


Render the ViewComponent to a string in your controller action using IViewRenderService. You'll need to inject this service into your controller. If you haven't already, you should configure it in your Startup.cs:

使用IViewRenderService将ViewComponent呈现为控制器操作中的字符串。您需要将此服务注入您的控制器。如果您尚未配置,则应在Startup.cs中进行配置:


// Startup.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using YourNamespace.Services;

public void ConfigureServices(IServiceCollection services)
{
// ...

services.AddTransient<IViewRenderService, ViewRenderService>();
}

Create a service that implements IViewRenderService to render the ViewComponent to a string. Here's a simple example:

创建实现IViewRenderService的服务以将ViewComponent呈现为字符串。下面是一个简单的例子:


// ViewRenderService.cs

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Routing;

public interface IViewRenderService
{
Task<string> RenderToStringAsync(string viewName, object model);
}

public class ViewRenderService : IViewRenderService
{
private readonly IHttpContextAccessor _contextAccessor;
private readonly IServiceProvider _serviceProvider;

public ViewRenderService(
IHttpContextAccessor contextAccessor,
IServiceProvider serviceProvider)
{
_contextAccessor = contextAccessor;
_serviceProvider = serviceProvider;
}

public async Task<string> RenderToStringAsync(string viewName, object model)
{
var httpContext = _contextAccessor.HttpContext ?? new DefaultHttpContext { RequestServices = _serviceProvider };
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(actionContext, viewName);
var viewContext = new ViewContext(
actionContext,
viewResult.View,
new ViewDataDictionary(model),
new TempDataDictionary(),
sw,
new HtmlHelperOptions()
);

await viewResult.View.RenderAsync(viewContext);

return sw.ToString();
}
}
}

In your controller action, render the ViewComponent to a string and include it in your JSON response:

在控制器操作中,将ViewComponent渲染为字符串并将其包含在JSON响应中:


[HttpGet]
public IActionResult LoadJobDetail(string job)
{
// Convert string to joblisting
JobListing jobDetail = JsonConvert.DeserializeObject<JobListing>(job);

if (jobDetail != null)
{
// Render the ViewComponent to a string
var viewComponentHtml = await _viewRenderService.RenderToStringAsync("YourViewComponentName", jobDetail);

return Json(new { response = viewComponentHtml, success = true, message = "Job detail successfully loaded" });
}
else
{
return Json(new { response = "", success = false, message = "Could not load the selected job listing" });
}
}

Replace "YourViewComponentName" with the actual name of your ViewComponent.

将“YourViewComponentName”替换为您的ViewComponent的实际名称。


Now, when you make an AJAX request to your LoadJobDetail action, it will return the rendered HTML of your ViewComponent as part of the JSON response. You can then use JavaScript to update the content of the corresponding element with this HTML.

现在,当您向LoadJobDetail操作发出AJAX请求时,它将返回呈现的ViewComponent的HTML作为JSON响应的一部分。然后,您可以使用JavaScript用该HTML更新相应元素的内容。


更多回答

This is just the simple version of the Invoke method. Subsequently I'll be changing the call to a post and handling some data retrieval and manipulations in there. Also I think I'll face a similar problem with partial views because I'll still need do pass the entire joblisting as a model to the partial view if I used that approach.

这只是Invoke方法的简单版本。随后,我将把调用更改为POST,并在其中处理一些数据检索和操作。另外,我认为使用部分视图也会面临类似的问题,因为如果我使用这种方法,我仍然需要将整个joblisting作为模型传递给部分视图。

OK then. Simply return the IActionResult that the ViewComponent method returns and drop this JSON thing

那好吧。只需返回ViewComponent方法返回的IActionResult并删除JSON内容

Sounds reasonable. But how do actually convert the ViewComponentResult as html string and return within the json response?

听起来很合理。但实际上如何将ViewComponentResult转换为html字符串并在json响应中返回呢?

I edited my post to show how can handle.

我编辑了我的帖子,以展示如何处理。

Please stop posting ChatGPT - stackoverflow.com/help/gpt-policy

请停止发布ChatGPT-stackoverflow.com/Help/gpt-policy

I couldn't understand ,but Ok. Finally, I reviewed the example and shared it.

我听不懂,不过好吧。最后,我回顾了这个例子并分享了它。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com