其实在浏览器端看情况并没有partial view或parent view这样的说法。浏览器只看到一个 html 文档。 Html.Partial 特别是 PartialViews 仅在服务器端有意义,它们确实可以帮助您。它使您能够在多个页面上重用部分视图,并在一个地方修改所有视图。当Razor渲染这个cshtml文件时,开始从上到下渲染,当遇到@Html.Partial("something")它执行返回Html编码 string 并显示返回的字符串。毕竟,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()){
<div class="row">
<div class="col-md-12">
@Html.Partial("_CurrentData", Model.CurrentItemDetails)
</div>
</div>
<div class="row">
<div class="col-md-2 col-md-offset-5">
<div>
<input type="submit" class="btn btn-primary" value="Submit" id="btnSubmit" />
<input type="button" class="btn btn-primary" value="Cancel" id="btnCancel" />
<br /><br />
</div>
</div>
</div>
}
并将您的发布操作添加到控制器,这非常好。
[HttpPost]
public ActionResult MainView(ItemDetails submittedItem)
{
//do stuff with model like persistence
var pvm = new ProductionViewModel();
pvm.CurrentItemDetails = submittedItem;
return View(pvm);
}
这将返回与新项目相同的视图
解决方案 2: 使用 Jquery 的 Ajax
这个解决方案已经给出。您将有两个选择;从服务器返回部分视图并将旧内容替换为从服务器返回的内容或返回 json 并通过 dom 操作更改内容。两种方法都有缺点。
Sippy 的回答很完美,我想添加的是代替 jquery ajax 方法的 load 方法对于返回静态视图更合理。
$("#partialViewDiv").load('@Url.Content("~/Controller/_CurrentData")');
解决方案 3:使用双向数据绑定或 Angular 等框架
当您想刷新局部视图时,您可能需要一些服务器生成的额外信息,例如新创建项目的 id。这就是为什么您需要与服务器交谈的原因,因为您已经有了动态的局部视图的新输入值。可能您想在同一页面某处的列表中显示所有已保存的项目,并且在从服务器返回创建的项目后,您必须手动添加它。因此,如果您的页面需要这样的情况,最好的方法是使用 Angular 等框架。这样,您可以刷新局部视图并毫不费力地做很多事情。我的 Demo 只是为了演示,你可以遵循许多设计原则。
这是主视图
<div ng-app="ItemApp" ng-controller="ItemController">
<form name="newTopicForm" data-ng-submit="save()">
<div class="row">
<div class="col-md-12">
@Html.Partial("_CurrentData", Model.CurrentItemDetails)
</div>
</div>
<div class="row">
<div class="col-md-2 col-md-offset-5">
<div>
<input type="submit" class="btn btn-primary" value="Submit" id="btnSubmit" />
<input type="button" class="btn btn-primary" value="Cancel" id="btnCancel" />
<br /><br />
</div>
</div>
</div>
</form>
</div>
局部视图
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Editor</h3>
</div>
<div class="panel-body">
<div class="row form-group">
<div class="col-sm-4 control-label text-right">
<strong>Name:</strong>
</div>
<div class="col-sm-8 control-label">
@Html.TextBoxFor(m => m.Name, new { @class = "formcontrol",data_ng_model="item.name",data_ng_init="item.name="+"'"+@Model.Name+"'"})
</div>
</div>
</div>
</div>
文本框通过 ng-model 属性绑定到 item.name,因此我们无需担心刷新视图。当 item.name 改变时,视图也会改变。(双向数据绑定)
包括 Angular 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);
}
你只需要处理对象所有视图操作在使用角度时都是通过两种方式数据绑定完成的。