再次使用ajax替换局部视图问题,以换掉部分视图。
我有一个部分视图,在加载页面时加载到页面上。此局部视图上有一个按钮,单击该按钮时,将使用另一个局部视图替换该局部视图。以前我用@Ajax.ActionLink
完成了这个并将页面模型作为参数传递给控制器。这工作正常。
然而,下一步是在新的局部视图上填写表格并提交它,这将返回另一个局部视图。我在这里询问了如何做到这一点,并使用jquery事件委托让它工作。
现在我试图用@Ajax.ActionLink
函数替换$.ajax
并遇到我的js脚本问题,其中视图或局部视图中已有的模型数据不存在由js传递给控制器。
这就是我的意思:
我有一个名为 ReviewPage 的页面,在加载时会调用一个返回局部视图的操作。该部分视图基于传递给控制器的页面模型的值来确定。通常,返回的视图是 _NoNotes :
@model GuestPointerAppV4.Models.ViewModels.NotesOnCompanyViewModel
<div id="no_company_notes">
<h4>Notes on Company</h4>
<div class="row col-sm-6 col-sm-offset-6">
<div class="text-center">
@Html.HiddenFor(item => Model.RequestId)
<div class="primary-action-bttn-border">
<div class="primary-action-bttn-bkg">
<button data-gp-ajax="true" data-gp-target="#no_company_notes" value="Save" action="@Url.Action("_CompanyNotesEditGet", "NewSignUpRequestReview")" method="get" class="btn btn-default primary-action-bttn">
Add Note
</button>
@*@Ajax.ActionLink("Add Note", "_CompanyNotesEditGet", Model, new AjaxOptions { UpdateTargetId = "company_notes", InsertionMode = InsertionMode.Replace, HttpMethod = "GET" }, new { @class = "btn btn-default primary-action-bttn" })*@
</div>
</div>
</div>
</div>
<div class="row text-center padding-25-top">
<p>There are no notes for this company. Do you want to add some?</p>
</div>
</div>
您会在上面的代码中注意到已注释掉的ajax操作链接。这就是我之前能够将模型传递给控制器的方式。
在此部分视图上单击按钮时,以下js会响应:
$(document).on('click', 'button[data-gp-ajax="true"]', function () {
var $form = $(this);
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: $form.serialize()
};
$.ajax(options).done (function (data) {
var $target = $($form.attr("data-gp-target"));
$target.replaceWith(data);
});
return false;
});
我想尽可能多地重用这个js,所以我利用自定义数据属性来帮助调用正确的函数(data-gp-ajax =&#34; true&#34;)并告诉脚本在哪里返回结果(data-gp-target =&#34;#targetiti&#34;)。
问题是在调试时,我发现虽然Model.RequestId
在页面上不是0,但是这个值不会被js拾取并传递给控制器。因此,当我的控制器查找数据时,它找不到它并返回null或0,具体取决于我试图通过的数据类型。
我做了一些研究,并尝试在局部视图中对模型进行编码,在模型输入后的部分视图代码的顶部使用以下代码:
@{
var val = Json.Encode(Model);
}
<script type="text/javascript">
var model1 = @Html.Raw(val)
</script>
然后,在我的js函数中,我尝试将model1传递给控制器,如下所示:
$(document).on('click', 'button[data-gp-ajax="true"]', function () {
var $form = $(this);
var $model = $(model1);
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: $model.serialize()
};
$.ajax(options).done (function (data) {
var $target = $($form.attr("data-gp-target"));
$target.replaceWith(data);
});
return false;
});
我也试过data: $model
和data: $model.first()
,但没有这样的运气。我设法调试并查看了我希望在$ model变量的js中看到的数据,所以我知道它已经进入那里但是当它没有传递给我的控制器时调用。
我真正想要的是一种干净可靠的方式,可以将页面模型传递给JavaScript,并将其传递给Controller,以便在返回部分视图之前执行某些操作替换原始的局部视图。
思想?
更新
以下是控制器的示例:
[HttpGet]
public ActionResult _CompanyNotesEditGet(NotesOnCompanyViewModel notesOnCompanyViewModel)
{
//Some actions are taken on the model passed in and then repopulated to notesOnCompanyViewModel
return PartialView("~/Views/NotesOnCompany/_CompanyNotesEdit.cshtml", notesOnCompanyViewModel);
}
但是,当我调试并且$ .ajax调用该操作时,notesOnCompanyViewModel为空。即使我可以看到有数据应该由js函数传递。
答案 0 :(得分:0)
您只需发送唯一ID即可。为此,您可以简单地覆盖按钮单击事件,并使用请求URL中的Id进行ajax调用。如果您想利用Url辅助方法生成操作方法的正确相对路径,您可以执行此操作并将该结果设置为按钮上的html5数据属性。
<button id="addNote"
data-url="@Url.Action("_CompanyNotesEditGet", "NewSignUpRequestReview",
new { id=Model.RequestId})" >
Add Note
</button>
假设您的_CompanyNotesEditGet
操作方法接受此Id
并根据需要返回值
public ActionResult _CompanyNotesEditGet(int id)
{
var vm= new NotesOnCompanyViewModel { RequestId=id };
//load other properties of vm as needed.
return PartialView(""~/Views/NotesOnCompany/_CompanyNotesEdit.cshtml",vm);
}
用于解释click事件的脚本。您可以使用load
方法进行ajax调用并更新DOM元素。
$(function(){
$(document).on("click","#addNote",function(e){
e.preventDefault();
var url=$(this).data("url");
$("#no_company_notes").load(url);
});
});
如果您正在编辑记事,在操作方法中,您可以使用传入的ID从数据库中读取您的记事实体。
假设页面中没有脚本错误,这应该可以正常工作。