如何使OnPostAsync在我的布局上呈现的PartialView上工作?

huangapple go评论72阅读模式
英文:

How to have OnPostAsync work on a PartialView rendered on my Layout?

问题

我有一个布局(_Layout.cshtml),我想要在它旁边作为一个独立页面渲染一个视图(Feedback.cshtml),同时保留RenderBody()的内容。视图本身将从布局的右侧滑出,使用按钮来控制它从右侧滑入和滑出。在该视图中有一个用于反馈的表单。以下是所提到的文件的示例代码:

Layout.cshtml

<div class="feedback">
    @await Html.PartialRender("Feedback", new FeedbackModel())
</div>
<div class="content">
    @RenderBody()
</div>

Feedback.cshtml

@model FeedbackModel
<div id="offcanvas formContainer">
  <form id="feedbackForm" method="post">
    <!-- 表单字段 -->
    <button type="submit">提交</button>
  </form>
</div>

Feedback.cshtml.cs

public class FeedbackModel : PageModel
{
    // 属性和字段

    public async Task<IActionResult> OnPostAsync()
    {
        // 处理数据,通过存储库方法将数据添加到数据库
        return Page();
    }
}

每次我点击反馈页面上的"提交"按钮时,什么都不会发生。它根本不调用OnPostAsync()方法。如果我在表单上附加asp-page-handler="@Model.OnPostAsync()"或者在按钮上附加onclick="@Model.OnPostAsync()",那么在布局完全加载之前,它会立即触发OnPostAsync()方法,而我甚至没有打开页面上的部分视图或点击按钮。有人可以提出解决方案吗?

我认为这个逻辑可以移动到一个ViewComponent中,但我不确定如何在唯一提供的方法是InvokeAsync()时执行OnPostAsync()

英文:

I have a layout (_Layout.cshtml) that i want to render a view (Feedback.cshtml) onto as a seperate page alongside the RenderBody(). The view itself will come off from the right hand side of the layout, using a button to toggle it paning to and from the right. On that view there is a form for feedback. Below is example code for the files mentioned:

Layout.cshtml

&lt;div class=&quot;feedback&quot;&gt;
    @await Html.PartialRender(&quot;Feedback&quot;, new FeedbackModel())
&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
    @RenderBody()
&lt;/div&gt;

Feedback.cshtml

@model FeedbackModel
&lt;div id=&quot;offcanvas formContainer&quot;&gt;
  &lt;form id=&quot;feedbackForm&quot; method=&quot;post&quot;&gt;
    &lt;!-- Form fields --&gt;
    &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
  &lt;/form&gt;
&lt;/div&gt;

Feedback.cshtml.cs

public class FeedbackModel : PageModel
{
    &lt;!-- Properties and fields --!&gt;

    public async Task&lt;IActionResult&gt; OnPostAsync()
    {
        &lt;!-- Transform data, Add data to DB via repository methods --!&gt;
        return Page();
    }
}

Everytime I click the "Submit" button on the Feedback page, it does nothing. It doesn't call the post method at all. If I append a asp-page-hander=&quot;@Model.OnPostAsync()&quot; on the form or an onclick=&quot;@Model.OnPostAsync()&quot; on the button - then before the layout even fully loads, it fires the OnPostAsync() method immediately, without me even opening the partial view on the page or clicking the button. Can anyone suggest a solution to this?

I thought this logic could instead be moved to a ViewComponent but I am not sure how I would be able to do OnPostAsync() when the only supplied method is InvokeAsync().

答案1

得分: 1

这里是一种方法。创建一个名为Feedback的Razor页面(如您所做),其中包含表单。以下是PageModel:

public class FeedbackModel : PageModel
{
    [BindProperty]
    public string Comments { get; set; }
    [BindProperty]
    public string Email { get; set; }
    public void OnGet()
    {
    }

    public void OnPost() 
    { 
        // 处理反馈        
    }
}

以下是视图:

@page
@model WebApplication3.Pages.FeedbackModel
@{
    Layout = null;
}
<h3 class="fw-light text-muted">提供您的反馈!</h3>
<form id="feedbackForm" method="post">
    <div class="form-group mb-3">
        <label asp-for="Email" class="control-label"></label>
        <input asp-for="Email" class="form-control" />
    </div>
    <div class="form-group mb-3">
        <label asp-for="Comments" class="control-label"></label>
        <textarea asp-for="Comments" class="form-control"></textarea>
    </div>
    <button type="button" class="btn btn-sm btn-success submit" data-bs-dismiss="offcanvas">提交</button>
</form>

请注意,Layout 设置为 null。我们只需要表单的HTML。此外,提交按钮的 type="button",因此在单击时不会提交表单。此外,它通过 data-bs-dismiss 属性与offcanvas关联,以在单击时关闭offcanvas。

将offcanvas的HTML添加到Layout页面:

<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasRight">
    <div class="offcanvas-body"></div>
</div>

以及一个用于打开它的按钮:

<button type="button" class="btn btn-primary feedback" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight">反馈</button>

最后,在Layout页面中添加以下脚本,当单击时获取表单的HTML并将其包含在offcanvas中。它还将点击事件处理程序连接到非提交按钮,以将表单内容提交到Feedback页面的OnPost处理程序:

<script>
    const feedbackButton = document.querySelector('button.feedback');
    const offCanvas = document.querySelector('#offcanvasRight .offcanvas-body');
    feedbackButton.addEventListener('click', _=>{
        fetch(`/feedback`).then(response => response.text()).then(html => {
            offCanvas.innerHTML = html;
            const form = offCanvas.querySelector('#feedbackForm');
            const submit = form.querySelector('button.submit');
            submit.addEventListener('click', _=>{
                const formData = new FormData(form);
                fetch(`/feedback`, {
                    method:'post',
                    body:new URLSearchParams(formData)
                });
            })
        })
    })
</script>

希望这有所帮助!

英文:

So here's one way. Create a Razor page called Feedback (as you have done) containing the form. Here's the PageModel:

public class FeedbackModel : PageModel
{
    [BindProperty]
    public string Comments { get; set; }
    [BindProperty]
    public string Email { get; set; }
    public void OnGet()
    {
    }

    public void OnPost() 
    { 
        // process the feedback        
    }
}

And here's the view:

@page
@model WebApplication3.Pages.FeedbackModel
@{
    Layout = null;
}
&lt;h3 class=&quot;fw-light text-muted&quot;&gt;Provide your feedback!&lt;/h3&gt;
&lt;form id=&quot;feedbackForm&quot; method=&quot;post&quot;&gt;
    &lt;div class=&quot;form-group mb-3&quot;&gt;
        &lt;label asp-for=&quot;Email&quot; class=&quot;control-label&quot;&gt;&lt;/label&gt;
        &lt;input asp-for=&quot;Email&quot; class=&quot;form-control&quot; /&gt;
    &lt;/div&gt;
    &lt;div class=&quot;form-group mb-3&quot;&gt;
        &lt;label asp-for=&quot;Comments&quot; class=&quot;control-label&quot;&gt;&lt;/label&gt;
        &lt;textarea asp-for=&quot;Comments&quot; class=&quot;form-control&quot;&gt;&lt;/textarea&gt;
    &lt;/div&gt;
    &lt;button type=&quot;button&quot; class=&quot;btn btn-sm btn-success submit&quot; data-bs-dismiss=&quot;offcanvas&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;

Note that the Layout is set to null. We only want the form HTML. Also, the submit button is type=&quot;button&quot; so that the form is NOT submitted when it is clicked. In addition, it is wired up with a data-bs-dismiss attribute so that it closes the offcanvas when clicked.

Add the offcanvas HTML to the Layout page:

&lt;div class=&quot;offcanvas offcanvas-end&quot; tabindex=&quot;-1&quot; id=&quot;offcanvasRight&quot;&gt;
    &lt;div class=&quot;offcanvas-body&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

Along with a button to open it:

&lt;button type=&quot;button&quot; class=&quot;btn btn-primary feedback&quot; data-bs-toggle=&quot;offcanvas&quot; data-bs-target=&quot;#offcanvasRight&quot;&gt;Feedback&lt;/button&gt;

Finally, add the following script to the Layout page that fetches the HTML for the form when it is clicked and includes it in the offcanvas. It also wires up a click event handler to the non-submit button that posts the content of the form to the OnPost handler of the Feedback page:

&lt;script&gt;
    const feedbackButton = document.querySelector(&#39;button.feedback&#39;);
    const offCanvas = document.querySelector(&#39;#offcanvasRight .offcanvas-body&#39;);
    feedbackButton.addEventListener(&#39;click&#39;, _=&gt;{
        fetch(`/feedback`).then(response =&gt; response.text()).then(html =&gt; {
            offCanvas.innerHTML = html;
            const form = offCanvas.querySelector(&#39;#feedbackForm&#39;);
            const submit = form.querySelector(&#39;button.submit&#39;);
            submit.addEventListener(&#39;click&#39;, _=&gt;{
                const formData = new FormData(form);
                fetch(`/feedback`, {
                    method:&#39;post&#39;,
                    body:new URLSearchParams(formData)
                });
            })
        })
    })
&lt;/script&gt;

huangapple
  • 本文由 发表于 2023年7月11日 01:06:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76655904.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定