在.Core 3.1 MVC中使用多个选项卡上的表单



在我的。Net Core 3.1 MVC项目中,我希望在一个页面上创建两个选项卡,每个选项卡上都有一个用于编辑数据的表单。最好的方法是什么?最好使用延迟加载,这样当选项卡处于活动状态时,表单数据才会被加载。

我已经尝试过页面和部分视图,但这没有正常工作,现在我想知道是否有一个直接的方法在。Core MVC中实现这一点。

我的代码:

basicprofile.cshtml

@page
@model VideoGallery.Presentation.Pages.Account.BasicUserProfile.InputModel
@{
}
<ul class="nav nav-tabs" id="myTab" role="tablist">
    <li class="nav-item">
        <a class="nav-link active" id="basicprofile-tab" data-toggle="tab" href="#basicprofile" aria-controls="basic" aria-selected="true">Account</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" id="extendedprofile-tab" data-toggle="tab" href="#extendedprofile" aria-controls="extended" aria-selected="false">Profile</a>
    </li>
</ul>
<div class="tab-content p-3 border-right border-left">
    <div class="tab-pane fade show active" id="basicprofile" role="tabpanel" aria-labelledby="basicprofile-tab">
        
    </div>
    <div class="tab-pane fade" id="extendedprofile" role="tabpanel" aria-labelledby="extendedprofile-tab"></div>
</div>
@section scripts{
    <script>
        var basicprofileLoaded = false;
        var extendedprofileLoaded = false;
        console.log("active");
        $(function () {
            $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                switch ($(e.target).attr('aria-controls')) {
                    case "basic":
                        if (!basicprofileLoaded) {
                            $('#basicprofile').load("@Url.Page("basicuserprofile", pageHandler:"PartialForm" )");
                            basicprofileLoaded = true;
                        }
                        break;
                    case "extended":
                        if (!extendedprofileLoaded) {
                            console.log("inside switch/ IF extended part");
                            $('#extendedprofile').load('/account/extendedprofile')
                            ordersLoaded = true;
                        }
                        break;
                }
            });
        });
    </script>
}

BasicUserProfile.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using VideoGallery.Presentation.Services;
namespace VideoGallery.Presentation.Pages.Account
{
    public class BasicUserProfile : PageModel
    {
        [BindProperty]
        public InputModel Input { get; set; }
        public class InputModel
        {
            public string LoginName { get; set; }
            public string Password { get; set; }
        }
        
        // both methods don't even get called, even when the page renders with an empty form.
        public async Task<IActionResult> OnGetAsync()
        {
            Input.Password = "test inpu";
            Input.LoginName = "other input";
            return Page();
        }
        public async Task<PartialViewResult> OnGetPartialForm()
        {
            Input.LoginName = "some name";    
            return Partial("_BasicProfilePartial", Input);
        }
    }
}

我有几个问题:

  1. 我的处理程序OnGet()和OnGetPartialForm()没有被触发。断点不会被击中。
  2. 加载BasicUserProfile页面时,基本选项卡应该是活动的,在第一个选项卡上显示表单。它有活动类,但数据没有加载。
  3. BasicProfile选项卡加载整个Page对象,在我单击基本选项卡之后(例如,当我在扩展选项卡上时)。它加载整个页面,尽管没有一个后端断点被击中。

我想做的是:在加载初始页面时,应该加载第一个选项卡(在加载时是活动的)的表单数据,无论是否包含数据。然后,如果用户切换到第二个选项卡,则应该加载该表单数据并显示在第二个选项卡下。显然,稍后,我想用post请求处理数据。

我的处理程序OnGet()和OnGetPartialForm()没有被触发。断点不会被击中。

这是因为您使用的是@model VideoGallery.Presentation.Pages.Account.BasicUserProfile.InputModel ,而不是PageModel。

更改为:

@page
@model VideoGallery.Presentation.Pages.Account.BasicUserProfile
<input asp-for="Input.Password" />
<input asp-for="Input.LoginName" />

$('#basicprofile').load("@Url.Page("basicuserprofile", pageHandler:"PartialForm")");

确保url被成功渲染。可以按下"F12",点击"Sources"面板,在浏览器中查看js源代码。在您的场景中,它似乎是:$('#basicprofile').load("@Url.Page("/Account/basicuserprofile", pageHandler:"PartialForm" )");

[BindProperty]公共InputModel输入{获取;设置;}

你需要记住初始化InputModel,否则当点击Input.Password = "test inpu";时它会得到错误:

[BindProperty]
public InputModel Input { get; set; } = new InputModel();

最新更新