如何在 AJAX Post 后重新加载创建视图?

问题描述 投票:0回答:1

我有两个模型类,电话和电话模型。

要创建新的

Telephone
,必须选择一个
TelephoneModel

我想在

Telephone
创建视图中添加一个模态来创建
TelephoneModel
,而无需离开视图。

TelephoneController
中,我已经添加了一个函数,该函数从模态中获取数据并在数据库中创建
TelephoneModel
。该函数通过 Ajax 从
Telephone
的创建视图调用。

它正确地将

TelephoneModel
添加到 BDD,但它并没有刷新我的视图。

在 BDD 中创建

TelephoneModel
后,如何让视图重新加载新信息以供选择?

型号:

namespace WebApplication1.Models
{
    public class Telefono
    {
        [Key]
        public int ID { get; set; }
        public required string Nombre { get; set; }
        public int IpId { get; set; }
        public virtual Ip? Ip { get; set; }
        public int ModeloTelefonoId { get; set; }
        public ModeloTelefono? ModeloTelefono { get; set; }

    }

   public class ModeloTelefono
   {

       public int ID { get; set; }
       public required string Nombre { get; set; }
       public required int MarcaID { get; set; } // Required foreign key property
       public Marca? Marca { get; set; } // Required reference navigation to principal
   }

}

功能:

    public async Task<IActionResult> AddModelo(string Modelo, int MarcaID, string Nombre, int subredID, int ipID)
    {
        var newModelo = new ModeloTelefono
        {
            Nombre = Modelo,
            MarcaID = MarcaID
        };

        if (newModelo != null)
        {
            _context.Add(newModelo);
            await _context.SaveChangesAsync();

            ViewBag.SubReds = _context.SubRed.ToList();
            ViewData["IpId"] = new SelectList(_context.Ip, "ID", "IpValue", ipID);
            ViewData["SubRedes"] = new SelectList(_context.SubRed, "ID", "Nombre", subredID);
            ViewData["ModeloTelefonoId"] = new SelectList(_context.ModeloTelefono, "ID", "Nombre", newModelo.ID);
            ViewData["Marcas"] = new SelectList(_context.Marca, "ID", "Nombre");


                            
            return View("Create", new Telefono { Nombre = Nombre });
            
        }
        else { return View(); }

    }

Ajax功能:

    function agregarModelo() {

        const Modelo = document.querySelector("#modeloInput").value
        const MarcaID = document.querySelector("#marcaSelect").value;
        const Nombre = document.querySelector("#Nombre").value;
        const subredID = document.querySelector("#Ip_SubRedID").value;
        const ipID = document.querySelector("#ipDropdown").value;


        $.ajax({
            url: '/Telefonoes/AddModelo',
            type: 'POST',
            dataType: 'JSON',
            data: { Modelo: Modelo, MarcaID: MarcaID, Nombre: Nombre, subredID: subredID, ipID: ipID }              
        });

    }
asp.net asp.net-mvc entity-framework-core
1个回答
0
投票

您的 Ajax 调用是一个 POST,旨在创建一个新模型,您正在更新 ViewData 以填充视图,尽管这仅在渲染时可用。您不希望 Ajax 调用返回 View() 响应,因为这通常用于 GET 请求,而不是 POST。相反,请考虑返回一个 JSON 响应对象,其中包含创建模型的成功/失败结果。例如:

public abstract class InsertResult
{
    public bool IsSuccessful { get; private set; }
    public string? Message { get; private set; }

    protected InsertResult() { }
}

public class InsertModeloResult : InsertResult
{
    protected InsertModeloResult() : base () { }

    public static InsertModeloResult Success()
    {
        return new InsertModeloResult { IsSucessful = true };
    }

    public static InsertModeloResult Failure(string message)
    {
        return new InsertModeloResult { Message = message };
    }
}

然后在您的方法中,您可以在模型成功插入后返回

Json(InsertModeloResult.Success())
,或者如果存在异常或验证失败等,则返回类似
Json(InsertModeloResult.Failure("The telephone model could not be inserted.");
或类似的内容。

Ajax 调用已设置为等待 JSON 返回并检查响应。如果您已经位于“创建”页面上,一个简单的选择就是触发页面刷新。这样做的缺点是,这是到服务器的另一次往返,因此在 POST 调用中刷新数据是没有意义的,因为重新加载将拉取当前数据并填充 ViewData。您通常会丢失用户在打开对话框创建新模型之前可能输入的任何信息。

所以简单的刷新看起来像:

$.ajax({
    url: '/Telefonoes/AddModelo',
    type: 'POST',
    dataType: 'JSON',
    data: { Modelo: Modelo, MarcaID: MarcaID, Nombre: Nombre, subredID: subredID, ipID: ipID }              
    success: function (result) {
        if (result.IsSuccessful) {
            window.location.reload();   // <- Will reload the current page
        } else {
            toastr.error(result.Message); // Display an error message using Toastr as an example.
        }
    }

一种较少破坏/浪费的选项是让 InsertModelResult 包含更新的电话型号列表,其中包括刚刚输入的默认选择的 ID,然后您的 Ajax 调用成功场景可以找到型号下拉元素并替换内部元素,选择合适的元素,而不依赖于整页刷新。

public class InsertModeloResult : InsertResult
{
    public SelectList<ModeloTelefono>? ModeloTelefonos { get; private set; }
    public int? SelectedModeloTelefonoId { get; private set; }

    protected InsertModeloResult() : base () { }

    public static InsertModeloResult Success(int selectedModeloTelefonoId, SelectList<ModeloTelefono> modeloTelefonos)
    {
        ArgumentNullException.ThrowIfNull(modeloTelefonos, nameof(modeloTelefonos));
        return new InsertModelResult
        {
            IsSuccessful = true,
            SelectedModeloTelefonoId = selectedModeloTelefonoId,
            ModeloTelefonos = modeloTelefonos 
        };
    }

    public static InsertModeloResult Failure(string message)
    {
        return new InsertModeloResult(false, message);
    }
}

使用提供的更新项目重新填充下拉列表将取决于您的渲染,但如果您在视图中使用 Razor 组件,则需要为该组件分配已知的 Id 或使用类似

@Html.IdFor
的内容来获取元素(如果使用表单绑定)。从那里您可以使用 result.ModeloTelefonos 中的新元素替换内部 HTML。它比强制页面刷新需要更多的工作,但对于为用户提供更无缝的异步体验来说可能是宝贵的经验。

    success: function (result) {
        if (result.IsSuccessful) {
            refreshModeloTelefono(result.ModeloTelefonos, result.SelectedModeloTelefonoId); // <- where this JS method finds the drop down and re-populates and selects the new item...
        } else {
            toastr.error(result.Message); // Display an error message using Toastr as an example.
        }
© www.soinside.com 2019 - 2024. All rights reserved.