使用mvc

时间:2017-09-01 22:40:20

标签: javascript jquery ajax asp.net-mvc

再次使用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: $modeldata: $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函数传递。

1 个答案:

答案 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从数据库中读取您的记事实体。

假设页面中没有脚本错误,这应该可以正常工作。