【问题标题】:Loading different models into partial views将不同的模型加载到局部视图中
【发布时间】:2015-08-19 03:37:09
【问题描述】:

我的主视图使用

@model IEnumerable<Ortund.Models.Reward>

我试图让用户在这个视图上做几件事而不必离开。

具体来说,我希望用户能够执行以下操作:

  • 查看他/她已领取的奖励(此用户有资格兑换的奖励)
  • 索取新收据,然后将与该收据关联的奖励添加到他/她当前的奖励中
  • 兑换他/她有资格获得的部分奖励,或一次性兑换全部奖励

我使用局部视图来实现这一点,因为我可以为每个局部视图设置一个新模型。

看起来像这样:

/Home/Index

if (Request.Cookies["Ortund"] == null)
{
    // render a login form
}
else
{
    <p>@String.Format("Welcome, {0}!", Convert.ToString(Request.Cookies["Ortund"]["username"])) <a id="claim-link">Claim New</a> | <a id="redeem-link">Redeem</a></p>

    @Html.Partial("_RewardsView")

    <!-- Render the new claim and redemption views as well -->
    <div class="claim-new">
        @Html.Partial("_ClaimsView")
    </div>
    <div class="redemption">
        @Html.Partial("_RedemptionView")
    </div>

_RewardsView

@model IEnumerable<Ortund.Models.Reward>
....

_ClaimsView

@model Ortund.Models.Receipt
....

_RedemptionView

@model IEnumerable<Ortund.Models.Reward>
....

我知道视图模型是首选方法,但由于我还没有弄清楚如何正确使用视图模型,所以我将采用这种方法。

我已经在另一个项目中这样做了,但是这次我收到一个错误,指出视图所需的字典时间与提供的不同(在这种特定情况下,我们在 Receipts 之间感到困惑和奖励)。

除了手动构建与模型没有关联的表单外,我不确定该怎么做,而是发布到正确的控制器...

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    如果你使用一个模型,但像这样构建:

    public class MainModel{
       public fakeOneModel fakeModelOneView{get; set;}
       public fakeTwomodel fakeModelTwoView{get; set;}
       public fakeThreemodel fakeModelThreeView{get; set;}
    }
    
    public class fakeOneModel{
        public string objectA1 {get; set;}
        public string objectA2 {get; set;}
        public string objectA3 {get; set;}
    }
    
    public class fakeTwoModel{
        public string objectB1 {get; set;}
        public string objectB2 {get; set;}
        public string objectB3 {get; set;}
    }
    
    public class fakeThreeModel{
        public string objectC1 {get; set;}
        public string objectC2 {get; set;}
        public string objectC3 {get; set;}
    }
    

    然后从您的视图中,您可以从一个模型访问所有类,例如:

    @Html.LabelFor(m=>m.fakeModelOneView.objectA1 )
    @Html.TextBoxFor(m=>m.fakeModelOneView.objectA1 )
    @Html.LabelFor(m=>m.fakeModelTwoView.objectB1 )
    @Html.TextBoxFor(m=>m.fakeModelTwoView.objectB1 )
    @Html.LabelFor(m=>m.fakeModelThreeView.objectC1 )
    @Html.TextBoxFor(m=>m.fakeModelThreeView.objectC1 )
    

    【讨论】:

      【解决方案2】:

      默认情况下,通过调用@Html.Partial("PartialViewName") 渲染的局部视图采用父视图的视图模型。

      您的主页模型应该包括您将传递给局部视图的模型:

      型号:

      public class IndexModel
      {
          public Ortund.Models.Receipt Receipt { get; set; }
          public IEnumerable<Ortund.Models.Reward> ClaimedRewards { get; set; }
          public IEnumerable<Ortund.Models.Reward> EligibleRewards { get; set; }
      }
      

      查看:

      当你调用局部视图时,指定你将传递给它的模型,例如

      @model IndexModel
      
      @Html.Partial("_RewardsView", Model.ClaimedRewards)
      @Html.Partial("_ClaimsView", Model.Receipt)
      @Html.Partial("_RedemptionView", Model.EligibleRewards)
      

      在一个页面上有多个表单是另一个问题。看 Multiple Forms in same page ASP.net MVC

      【讨论】:

      • 所以,简而言之:使用视图模型?
      【解决方案3】:

      所以,简而言之:使用视图模型?

      是的,基本上。很多时候,视图模型只是用来满足您的需要,您不妨学习使用它们。

      但是,在这种情况下,您可以坚持更长时间,因为您也可以使用子操作来实现您正在寻找的东西。本质上,它看起来像这样:

      控制器

      [ChildActionOnly]
      public ActionResult Rewards()
      {
          // fetch rewards
      
          return PartialView("_Rewards", rewards)
      }
      

      查看

      @Html.Action("Rewards")
      

      【讨论】:

        【解决方案4】:

        如果你想使用 ajax 来更新 Views,那么你可以试试MultiPartials。它们会更新您使用 Id 定义的任何元素的额外好处,这意味着您可以使用数据更新多个 div,而不必担心管理复杂的视图模型。

        @Ajax.ActionLink("ActionLink", "ActionLinkClick", new AjaxOptions { OnSuccess = "MultipartialUpdate" })
        
        public ActionResult ActionLinkClick()
        {
             MultipartialResult result = new MultipartialResult(this);
        
              result.AddView("_Div1", "Div1", new Div1Model("ActionLink clicked"));
              result.AddView("_Div2", "Div2", new Div2Model("ActionLink clicked"));
              result.AddContent("ActionLink", "LastClickedSpan");
              result.AddScript("alert ('ActionLink clicked');");
        
             return result;
        

        }

        然后在视图中

        @using(Ajax.BeginForm("FormSubmit", new AjaxOptions { OnSuccess =      "MultipartialUpdate" }))
        {
              <input type="submit" value="Submit">
        }
        

        这段代码 sn-p 来自上述链接,您可以创建尽可能多的部分,而无需创建复杂的代码来管理所有部分。

        【讨论】:

          猜你喜欢
          • 2015-06-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-28
          • 1970-01-01
          • 1970-01-01
          • 2015-05-31
          相关资源
          最近更新 更多