【问题标题】:Update a partial view with a string from another partial view on submit?在提交时使用来自另一个部分视图的字符串更新部分视图?
【发布时间】:2018-05-04 03:18:28
【问题描述】:

我是 MVC 和 Web Api 的新手,但遇到了困难。 请注意:我使用的是 ApiControllers,而不是 Controllers!

情况 我有两种片面的看法。第一个有下拉列表和提交按钮。第二个只是一个确认视图,显示用户提交后用户选择的内容。单击提交时,我想将一个字符串(包含用户的组合选择)发送到第二个局部视图并更新它。

问题 当我在第一个局部视图上按提交时,我想向第二个局部视图发送一个字符串并更新第二个局部视图。我怎样才能做到这一点?当然,字符串的发送可以是间接的,例如视图到控制器然后返回到视图。我只想知道至少一个方法。

再次注意,我使用的是 Web Api 控制器,而不是控制器。大多数人使用普通的控制器,这不适用于我。它们不一样。

我尝试过的事情/我认为我无法从其他 StackOverflow 答案中做的事情:

  1. 我不能使用控制器方法来返回部分视图,就像在这个非常相似的问题Same question but not with ApiControllers 中一样。
  2. 我无法将任何数据存储到类中,因此我无法使用 @model ExampleClass 强类型化视图以使用 @Model.ExampleProperty 访问存储的内容。
  3. 由于我无法将数据存储到类中或从 View(model) 等控制器方法返回模型,因此我也无法使用 Html.DropDownListFor(model => model.SelectedValue) 将 SelectedValue 存储到我的模型中并访问它在其他部分视图中。为了填充我的下拉列表,我手动添加了一个 div,称为返回列表的 GET 方法,并通过附加到列表来填充列表。

那么,我到底能做什么?我也尝试过 ViewData,但在 Controller 方法完成后,存储的数据不会持续。我没主意了。我希望我弄错了什么,错过了一个方法,因为感觉它不应该这么难。如果您甚至可以简要描述一下我将如何传输字符串和/或在按下提交后更新第二个局部视图的流程,那将不胜感激!

提前非常感谢!

模型类

public class Vehicle
    {
        public class Make
        {
            public int MakeId { get; set; }
            public string MakeName { get; set; }
        }

        public class Model
        {
            public int ModelId { get; set; }
            public string ModelName { get; set; }
        }
    }

ApiController 类。 ViewData 似乎没有保存其内容。我想用第一种 POST 方法将用户的选择存储到 ViewData 中,并用第二种方法 GET 选择,但是 ViewData 的内容已经变成了 null。

public class VehicleController : ApiController
    {
        public ViewDataDictionary ViewData = new ViewDataDictionary();

        [HttpPost]
        public void StoreMakeAndModel(string user_selections){
            ViewData["message"] = user_selections;
        }

        [HttpGet]
        public string ConfirmationMessage(){
            ViewData["message"] = "You selected the " + ViewData["message"].ToString();
            return ViewData["message"].ToString();
        }

        //This returns a list to populate a drop down list
        [HttpGet]
        public IEnumerable<Vehicle.Make> Makes(){
            //This function reads from xml and returns List<Vehicle.Make>
            ...
            return makesList;
        }

        //This returns a list to populate a drop down list
        [HttpGet]
        public IEnumerable<Vehicle.Model> Models(int id){
            //This function reads from xml the car models that match the make id
            ...
            return modelsList;
        }
    }    

第一个部分视图 它有 2 个下拉列表和提交按钮。一旦表单提交呈现第二个部分视图,就会显示一个隐藏的 div。我希望它仅在显示时才加载,以便我可以使用 $(document).ready(function()) 在那里显示我的字符串,但它会在主页加载时加载,即使它是隐藏的。所以我不知道在第一个部分视图提交后如何用字符串更新它。

<select required id="makes_DDL" name="makes_DDL"></select>

<select required id="models_DDL" name="models_DDL"></select>

<input type="submit" id="submit_button" value="Submit Form" onclick="formSubmit()" />

<div id="thank_you_div" style="display:none;">
    @Html.Partial("_ThankYou");
</div>

    function formSubmit() {
        //Combines the make and model into one string, Ex: Chevrolet Malibu
        var parameter = $("#makes_DDL").children(":selected").text() + " " 
             + $("#models_DDL").children(":selected").text();
        var uri = "api/vehicle/storemakeandmodel/" + parameter;

        $.ajax({
            url: uri,
            type: "post",
            updatetargetid: "thank_you_div",
            success: function (data) {
                $("#thank_you_div").show();
            },
            });
}

我的列表人口如下所示;这是我的第一个清单。我无法让@Html.DropDownListFor 工作,因为我无法从控制器方法返回 View(model) 之类的内容,因此无法存储任何内容。

$(document).ready(function () {
        $.getJSON("api/vehicle/makes", function (makes) {
            $("#makes_DDL").append("<option value= ''>Select a make</option>");
            $.each(makes, function (id, make) {
                $("#makes_DDL").append("<option value=" + make.MakeId + ">" + make.MakeName + "</option>");
            });
        });
    });

第二部分视图它试图获取存储在 ViewData 中的消息,但它已经消失了,GETS 为空。

<div id="thank_you_div">Thank you!</div>

<script type="text/javascript">
    $(document).ready(function () {
        alert("Thank You Partial View ready!");
        $.ajax({
            url: "api/vehicle/confirmationmessage",
            type: "get",
            updatetargetid: "thank_you_div",
            success: function (message) {
                $("#thank_you_div").html(message)
            }
        });
    })
</script>

【问题讨论】:

  • 您目前如何渲染具有两个下拉菜单的页面?不是通过控制器动作吗?
  • 另外,为什么你不能从你的第一个 ajax 调用中得到响应并简单地用响应更新一些 DOM 元素并显示它? $("#thank_you_div").html(data).show()。移除第二个局部视图
  • 有 2 个控制器方法,每个方法返回一个 IEnumerable 品牌或型号。每种方法都会填充第一个局部视图中的 2 个下拉列表中的每一个。我填充它的方式是,我使用 getJSON 从我的控制器方法返回列表,然后使用 javascript 循环遍历品牌或模型,并将它们 1 逐 1 附加到选择元素(makes_DDL 和 modell_DDL 是元素 id)。这样它们就成为实际的下拉列表而不是空的选择元素。我将我的列表人口包括在底部附近。也许这效率低下......?但我无法为 Web Api 找到不同的方式。
  • 你还是没有回答我的问题。你为什么还要关心第二个局部视图。让您的第一个 ajax 调用返回您想要的字符串(来自 StoreMakeAndModel),并在该 ajax 调用的成功处理程序中,使用响应(字符串)更新 DOM
  • 如果我想不出另一种方法,我可能会这样做,但我试图用部分视图来做,所以我想找出一种方法。我同意这种方式似乎更容易并且达到相同的目的,但这不是他们挑战我做的事情哈哈。也很抱歉,我不是故意忽略你的问题,只是网速慢。我想学习或知道是否有办法为未来学习。我觉得一定有办法,否则 ApiController 似乎非常有限。

标签: c# jquery asp.net-mvc asp.net-mvc-4 asp.net-web-api


【解决方案1】:

看看您的 ApiController 操作方法。

[HttpPost]
public void StoreMakeAndModel(string user_selections)
{
   ViewData["message"] = user_selections;
}
[HttpGet]
public string ConfirmationMessage()
{
    ViewData["message"] = "You selected the " + ViewData["message"].ToString();
    return ViewData["message"].ToString();
}

看起来您正在尝试在调用第一个方法时将数据存储到 ViewData,并在您进行第二个 ajax 调用时在第二个方法中读取它。 但这行不通!因为http是无状态的。您的第二个电话不知道您的第一个电话做了什么。您不能将数据存储在 ViewData 中以在多个 http 请求之间进行访问。在 api 控制器中使用 ViewData 根本没有意义。 Api 控制器端点应该纯粹是为了返回数据。

在你的情况下,你应该做的是,让你的第一个方法返回你想要的字符串消息。在第一次 ajax 调用的成功处理程序中,您将在成功回调中获取此字符串(来自 api 方法的响应)。您可以根据需要使用它来更新 DOM。

也不需要部分视图。您只需要一个容器 div 元素来显示响应。

<select required id="makes_DDL" name="makes_DDL"></select>
<select required id="models_DDL" name="models_DDL"></select>

<input type="submit" id="submit_button" value="Submit Form" onclick="formSubmit()" />

<div id="thank_you_div" style="display:none;"></div>

现在在您的第一个 ajax 调用的成功回调中,使用返回的响应更新 DOM。

另外$.ajax 没有名为updatetargetid 的设置属性!

function formSubmit() {
    //Combines the make and model into one string, Ex: Chevrolet Malibu
    var parameter = $("#makes_DDL").children(":selected").text() + " " 
        + $("#models_DDL").children(":selected").text();
    var uri = "api/vehicle/?user_selections=" + parameter;
    $.ajax({
        url: uri,
        type: "post"
    }).done(function(res) {
        $("#thank_you_div").html(res).show();
    }).fail(function(x, v, e) {
        console.log(e);
    });
}

假设你的 api 控制器方法返回你想要的字符串

[HttpPost]
public string StoreMakeAndModel(string user_selections)
{
    return  "You selected the "+user_selections;
}

【讨论】:

  • 非常感谢shyju!我没有意识到这就是无国籍的含义,但这也解释了我的许多其他困惑!感谢您也包含所有代码。不过,我仍然很好奇,尤其是你所说的它是如何无状态的并且方法应该只返回数据。可以肯定地说,就以某种方式从一个局部视图到另一个局部视图获取字符串而言,听起来不可能按照我的要求去做,至少如果我坚持使用 API 控制器和 RESTful Web 应用程序的话?
  • 可以在 2 次调用之间持久化数据(例如将数据存储在表/文件之类的某个地方并从那里读取)。但它扼杀了 http 的无状态特性。
  • 感谢您的快速回复。这对我来说很有意义。你描述的可能的方法听起来根本不像他们想要我做的,所以听起来他们用错了或忽略了一些东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多