父窗口和子窗口之间的MVC传递模型

时间:2016-04-19 21:12:34

标签: javascript jquery asp.net-mvc tempdata

提前致谢。请原谅我的语法。我尽力解释我的问题在我寻求解决下面的问题时,我开始首先开发POC。

C# MVC No submit pass object between views

我在使用TempData对象时遇到问题,并在我的父弹出窗口和子弹出窗口之间传递我的模型。我的问题是我正在做TempData [“StudentViewModel”] 2次。 第一次插入和第一次阅读是好的,但第二次阅读,即使我确保我在读取之前第二次插入不工作。

我会尽力解释清楚。

我有一个名为Class.cshtml的ASP.NET页面。它将具有所有类的网格。用户将选择一个ClassName列,它将Students.cshtml打开为一个新的弹出窗口,其中包含一个带有StudentName和Address列的网格。用户将选择StudentName,然后打开另一个名为StudentDetails.cshtml的弹出窗口。

我们有一个ClassController.cs,它被所有弹出窗口使用,并且有C#方法。 ClassController.js包含所有javscript代码。

public ActionResult GetStudentsDetails()
{
  // this will create students for each class. 
  //Inside student for each class it will also create Student Details.

   // First Insert
   TempData["StudentViewModel"] = studentViewModel;
   return View("Students", studentViewModel);    
}

Students.cshtml是一个现有的弹出窗口,如下所示

<div>

//this is in for loop
string anchorElementId = string.Format("AnchorElementId_{0}", i);                                                      
string selectedIndex = i.ToString();
string name = Model.Students[i].Name;

 <input class="ButtonLikeHyperLink"
        id="myBtnId"
        onclick="ShowStudentDetails(@selectedIndex, '@name', '@anchorElementId')"
        value="@Model.Students[i].Name"
        type="button"/>


//for loop ends here

 //First read
<span id="lblHDNStudentViewModel">  
@Newtonsoft.Json.JsonConvert.SerializeObject(TempData["StudentViewModel"] as StudentViewModel)
</span>

</div>

一旦用户在Students.cshtml弹出窗口中选择任何StudentName,就会调用以下js方法,该方法将打开一个具有特定学生详细信息的子窗口弹出窗口。

ClassController.js

function ShowStudentDetails(selectedIndex, name, anchorElementId)
{
    var inputParam = {};
    var hiddenField = document.getElementById("lblHDNStudentViewModel");
    if (hiddenField != null)
    {          
        inputParam.StudentVM = JSON.parse(hiddenField.innerText);

        inputParam.selectedIndex = selectedIndex;
        inputParam.name = name;
        inputParam.anchorElementId = anchorElementId;

        // __callback is our custom method to call controller action method
        var retVal = __callback("OnNameSelected", inputParam);
        var postedData = JSON.parse(retVal.return_value);
        if (postedData.Success == true)
        {
          // i need to do like below since Model to my popup is dynamic
         multipleMatchPopup = window.open('', '', properties);                       
         multipleMatchPopup.document.write(postedData.PartialViewHtml); 
        }
    }
}

ClassController.cs

public JsonResult OnNameSelected(StudentViewModel StudentVM, int selectedIndex, string name, string anchorElementId)
{ 
// this will create student name details viewmodel for selected name and modify StudentViewModel object.
// for example
StudentDetailsViewModel vm = StudentVM[selectedIndex].DetailsVM;

//since user made selection update few properties in vm

StudentVM[selectedIndex].DetailsVM = vm;

//Second insert
// make sure to set tempdata before RenderPartialViewToString
TempData["StudentViewModel"] = StudentVM;

string sHtml = this.RenderPartialViewToString("~/Views/_PartialStudentDetailsPopup.cshtml", vm);

 return Json(new
            {
                Success = true,
                data = StudentVM,
                PartialViewHtml = sHtml,
                JsonRequestBehavior.AllowGet
            });
}

在StudentDetails.cshtml弹出窗口中,我喜欢这个

<div>
.....
 <input class="ButtonLikeHyperLink"
         id="@buttonId"
          onclick="OnUserSelectStudentDetails()"
          value="[Select]"
          type="button" />     

  //Second read
 //in fiddler innertext is show as null                            
<span id="lblHDNStudentDetailsViewModel">
 @Newtonsoft.Json.JsonConvert.SerializeObject(TempData["StudentViewModel"] as StudentViewModel)
</span>
</div>

ClassController.js

function OnUserSelectStudentDetails()
{

 var inputParam = {};

 var hiddenField = document.getElementById("lblHDNStudentDetailsViewModel");
  if (hiddenField != null)
  {        
     //hiddenField.innerText is null
     inputParam.StudentVM = JSON.parse(hiddenField.innerText);

      var retVal = __FAFdoCallback("OnUserSelectLenderMatchingFee", inputParam);
        ...
    }
}

ClassController.cs

public JsonResult OnUserSelectLenderMatchingFee(StudentViewModel StudentVM)
{
//StudentVM is null here
}

更新

我对这个问题感到很愚蠢。作为伟大的侦探, Hercule Poirot 说,“伟大的灰色细胞不起作用”,我的也没有工作 在这种情况下。有时我们认为我们监督基础知识的方框离我们这么远。我觉得这件事不能这么简单,所以我在考虑TempData等等,忘记了我的父弹出已经有一个隐藏字段的基本点,我可以从中读取并在我的javascript方法中写入它父窗口和子窗口弹出窗口,并将其传递给控制器​​操作方法,并返回更新和一致的模型。

采用这种基本解决方案,这就是我所做的

Students.cshtml

<span id="lblHDNStudentViewModel">  
@Newtonsoft.Json.JsonConvert.SerializeObject(Model)
</span>

在ClassController.js

中的父窗口javascript方法中读取此内容
function ShowStudentDetails(selectedIndex, name, anchorElementId)
{
    var inputParam = {};

    //read
    var hiddenField = document.getElementById("lblHDNStudentViewModel");
}

从ClassController.js

中的子窗口javascript方法中读取此内容
function OnUserSelectStudentDetails()
{

 var inputParam = {};

 // read in child window and access parent window element
  var hiddenField = window.opener.document.getElementById("lblHDNStudentViewModel");
}

从父窗口javascript方法写回父窗口元素,如下所示

document.getElementById("lblHdnCDLenderViewModel").innerText = JSON.stringify(postedData.data);

从子窗口javascript方法写回父窗口元素,如下所示

window.opener.document.getElementById("lblHdnCDLenderViewModel").innerText = JSON.stringify(postedData.data);

0 个答案:

没有答案