从父视图提交部分视图数据
如何从父视图提交部分视图数据。
我是MVC的新手,
我创建了一个局部视图_CurrentData ,其中包含编辑器控件 – 文本框等
并在主视图中添加了“提交”按钮:
@Html.Partial("_CurrentData", Model.CurrentItemDetails)
视图模型
public class ProductionViewModel { public ItemDetails CurrentItemDetails { get; set; } } public class ItemDetails { public int ID { get; set; } public string Name { get; set; } }
视图
Editor
Name: @Html.TextBoxFor(m => m.Name , new { @class = "form-control" })
现在单击’btnSubmit’我想将数据从_CurrentData视图提交到服务器,然后刷新局部视图,
怎么做到这一点?
你要的是什么
您要求的function是AJAX。 AJAX请求是“异步”,在最基本的级别意味着可以启动和响应HTTP请求,而无需刷新页面。
正如有人写评论你的问题,jQuery可以使用,并提供了一个很好的方式来做AJAX请求,但如果你只是为了一个AJAX请求包含整个jQuery库,很多人可能会哭。
JavaScript的
所以在JavaScript中这是一个更复杂的问题,这里有一些例子。 我不打算告诉你如何在JavaScript中完成它只是因为我现在没有很多时间,但我可能会在稍后更新答案。 如果可以的话,我可能会建议你这样做。
jQuery的
在jQuery中这很容易。 AJAX请求的文档在这里 。
基本上您需要做的是向服务器发出请求,以便它可以更新您的部分视图数据 ,然后返回新的部分视图,以便用您替换当前的HTML。 它看起来像:
$.fn.serializeObject = function () { var o = {}; var a = this.serializeArray(); $.each(a, function () { if (o[this.name]) { if (!o[this.name].push) { o[this.name] = [o[this.name]]; } o[this.name].push(this.value || ''); } else { o[this.name] = this.value || ''; } }); return o; }; $.ajax({ url: '@Url.Content("~/Controller/_CurrentData")', type: 'POST', data: { //partialViewForm relates to the form element in your partial view model: JSON.stringify($('#partialViewForm').serializeObject()); }, success: function (response) { if (response) { //partialViewDiv relates to the div in which your partial view is rendered $('#partialViewDiv').html(response); } }, error: function (xhr, ajaxOptions, thrownError) { alert(xhr.status); alert(thrownError); } });
上面会假设你有这样的东西作为你的控制器方法:
[HttpPost] public ActionResult _CurrentData(ItemDetails model) { //do stuff with model here return PartialView("_CurrentData", model); }
所以这基本上就是你联系控制器的方式。 要从您的网页调用该ajax,您需要在窗体中的部分视图中使用一个按钮,您可以使用event.preventDefault()
覆盖该窗体。
实际上,当您查看浏览器端的情况时,没有像部分视图或父视图这样的语句。 浏览器只能看到一个html文档。 Html.Partial
尤其是PartialViews仅在服务器端有意义,它们确实可以为您提供帮助。 它使您能够在多个页面和一个地方重用部分视图来修改所有部分视图。 当Razor渲染这个cshtml文件时,开始从上到下渲染,当它遇到@Html.Partial("something")
它会执行返回Html编码 字符串并显示返回字符串的方法。 毕竟,Razor会返回一个完整的html页面。 因此,当您从html 提交数据时,唯一重要的是哪个输入类型具有哪个name属性。
解决方案1:没有Ajax根据您的主视图,您的get方法就是这样。
// GET: Item public ActionResult MainView() { var _itemDetail = new ItemDetails { ID = 1, Name = "Item1" }; //you get this item somewhere maybe db var pvm = new ProductionViewModel(); pvm.CurrentItemDetails = _itemDetail; //add item to viewmodel return View(pvm); }
我假设你有表格标签,只需更改你的按钮类型即可提交
@using(Html.BeginForm()){ @Html.Partial("_CurrentData", Model.CurrentItemDetails)
}
并将你的post动作添加到控制器,这非常好。
[HttpPost] public ActionResult MainView(ItemDetails submittedItem) { //do stuff with model like persistence var pvm = new ProductionViewModel(); pvm.CurrentItemDetails = submittedItem; return View(pvm); }
这将返回与新项目相同的视图
解决方案2: Ajax使用Jquery已经给出了这个解决方案。 你有两个选择; 从服务器返回部分视图并将旧内容替换为从服务器返回的内容或返回json,并通过dom操作更改内容。 两种方法都有缺点。 Sippy的答案是完美的,我想要添加的是jquery ajax方法,加载方法对于返回静态视图更合理。
$("#partialViewDiv").load('@Url.Content("~/Controller/_CurrentData")');
解决方案3:使用双向数据绑定或类似Angular的框架当您想要刷新局部视图时,您可能需要一些额外的信息,这些信息是服务器生成的,就像新创建的项目的ID一样。 这就是您需要与服务器通信的原因,因为您已经拥有了部分视图的新输入值。 可能是您希望在同一页面的某个位置显示列表中的所有已保存项目,并且在从服务器返回创建的项目后,您必须手动添加它。 因此,如果您的页面需要这样的情况,那么最佳方式是使用像angular这样的框架。 通过这种方式,您可以刷新部分视图并毫不费力地制作很多东西。 我的演示仅用于演示,您可以遵循许多设计原则。
这是主要观点
局部视图
Editor
Name: @Html.TextBoxFor(m => m.Name, new { @class = "formcontrol",data_ng_model="item.name",data_ng_init="item.name="+"'"+@Model.Name+"'"})
文本框绑定到具有ng-model属性的item.name,因此我们无需担心刷新视图。 当item.name更改视图更改时。 (双向数据绑定)包括角度js,这是自定义js
var myApp = angular.module('ItemApp', []); myApp.controller('ItemController', function ($scope, $http,$q) { $scope.itemList = {}; $scope.save = function () { $http.post("mainview", $scope.item). then(function (result) { $scope.item.name = result.data.Name; //update from server //it is enoguh to refresh //your partial view data itemList.splice(0, 0, result.data);//add list may be you need to //display in the view }, function () { console.log(error); }); }; });
和服务器端代码
[HttpPost] public ActionResult MainView(ItemDetails SubmittedItem) { //do stuff with model like persistence SubmittedItem.ID = 1; return Json(SubmittedItem); }
您只需要处理对象所有视图操作都是在使用angular时通过双向数据bindig完成的。
是的,主视图是纯HTML或由多个局部视图+主视图组成,当它在浏览器中呈现时,它将被视为一个单独的HTML而不是部分。通过说,您将可以访问DOM的无论是在局部视图还是主视图中。因此,根据我的个人经验,如果您已经决定使用Jquery post方法构建自己的模型/视图模型来帮助它,那么放置提交按钮的位置并不重要。
但是,有些情况下,您将使用部分视图的每个级别的部分更新按钮
@using (Ajax.BeginForm
解决方案1 :
您可以简单地将主页中的input
s包装在Ajax form
元素中,并在其中调用@Html.Partial("_CurrentData", Model.CurrentItemDetails)
,一切都会正常工作。
解决方案2 :
在单击btnSubmit元素( 定义单击事件 )之后,不使用带有一些JavaScript代码的form
标记来查找目标input
然后将它们序列化以准备发送到服务器的操作方法。
两个解决方案的共同部分是编写一个ajax方法,它响应更新页面而不刷新,如:
public JsonResult GetResponse(ItemDetails model) { return Json(/*data*/, /*behavior*/); }