【问题标题】:Update Model Value in a Previously Loaded Razor Partial View在先前加载的 Razor 局部视图中更新模型值
【发布时间】:2017-08-16 13:47:18
【问题描述】:

我有一个视图,它在视图呈现时加载一组模块(我们将说其他部分视图)。

所以在主视图中这样想:

<div>
    @Html.PartialView("~/Views/MyApp/Partials/Module1.cshtml");
</div>
<div>
    @Html.PartialView("~/Views/MyApp/Partials/Module2.cshtml");
</div>
<div>
    @Html.PartialView("~/Views/MyApp/Partials/Module3.cshtml");
</div>

部分视图Module2.cshtml 中有一个模型值已更改。实际上,它在 Module2 视图的操作中被更改。我在public ActionResult RenderChecklist(Model pageModel, IGrouping&lt;string, ChecklistItem&gt; list, int checklistCount)中设置模型值:

if (itemCounter == itemCheckedCounter)
{
    priorityCounter++;
    pageModel.MyAppInfo.ChecklistPriorityLevel = priorityCounter;
    listRestrict = "no-restrict";
    overlayShow = "hidden";
}
else
{
    listRestrict = "no-restrict";
    overlayShow = "hidden";
}

根据ChecklistPriorityLevel 的值确定是否在Module1Module3 等中显示叠加层,但由于Module1Module2 之前加载,@987654332 中的ChecklistPriorityLevel 的值@ 总是从 0 开始。

在每个模块中调用的局部视图中的代码是这样的:

@if (moduleRestrict && !(moduleRestrictPriorityLevel <= checklistPriority) && !Model.GetValue<bool>("moduleRestrictBypass"))
{
    const string moduleLockMessage = "This section is locked.";

    <div class="module overlay show">
        <img src="/assets/myapp/images/lock.png" alt="Module Lock">
        <p>@moduleLockMessage</p>
    </div>
}

模型中的相关代码只是一个常规的get,此时设置:

namespace MyApp.Core.MySite.Models
{
    /// <summary>
    ///     Model for MySite.
    /// </summary>
    public class MyAppInfoModel
    {
        ... //other models

        [Ignore]
        public int ChecklistPriorityLevel { get; set; }
    }
}

所以我的问题是如何让这个模型的值变化来触发已经加载的其他模块(部分视图)的变化?

免责声明:出于隐私目的,我更改了一些实际代码。我只是想提供足够的信息让观众了解我想要做什么。我正在寻找最佳选择,无论是异步的还是其他方式,以正确获取其他部分视图中的值,而不管哪个部分首先加载。

【问题讨论】:

    标签: c# .net asp.net-mvc razor umbraco


    【解决方案1】:

    解决我自己的问题(但我仍然很想看看如何处理)

    因此,对于我的特定问题,我决定在加载任何模块之前强制设置模型的值。我的应用程序的工作方式是,Module2 实际上可以在任何位置,并且任何模块都可以在 Module2 之前或之后。模块的顺序在后台确定。所以我只是决定创建一个 SurfaceController 并在主视图上获取数据(清单),但是我必须在“Module2”中再次获取数据,这是我的 ChecklistModule。我真的不喜欢重复检查清单两次,但为了获得 ChecklistPriorityLevel 值,我必须迭代检查清单。

    所以在我的主视图中,调用如下:

    MyAppChecklistController.SetChecklistPriorityLevel(Model);
    

    那我的方法是:

    public static void SetChecklistPriorityLevel(MyAppRenderModel pageModel)
    {
        var checklist = GetCheckList(pageModel);
        var priorityCounter = 1;
    
        foreach (var list in checklist)
        {
            var listCount = list.Count();
            var itemData = new ValueTuple<int, int, string>(1, 1, null);
    
            itemData = list.OrderBy(x => x.IsChecked).ThenBy(x => x.SortOrder).Aggregate(itemData,
                (current, item) => GetItemList(item, current.Item1, current.Item2, current.Item3, listCount));
    
            var itemCounter = itemData.Item1;
            var itemCheckedCounter = itemData.Item2;
            //  var itemList = itemData.Item3;
    
            priorityCounter = GetPriorityLevel(itemCounter, itemCheckedCounter, priorityCounter);
    
            pageModel.ChecklistPriorityLevel = priorityCounter;
        }
    }
    

    然后当我在 ChecklistModule 局部视图中渲染清单时:

    [ChildActionOnly]
    public ActionResult RenderChecklist(IGrouping<string, ChecklistItem> list,
            int checklistCount, int checklistCounter, int priorityCounter)
    {
        var parentFolder = list.First().UmbracoContent.Parent;
        var listCount = list.Count();
        var itemData = new ValueTuple<int, int, string>(1, 1, null);
        var color = GetChecklistColorValue(parentFolder);
    
        itemData = list.OrderBy(x => x.IsChecked).ThenBy(x => x.SortOrder).Aggregate(itemData,
            (current, item) => GetItemList(item, current.Item1, current.Item2, current.Item3, listCount));
    
        var itemCounter = itemData.Item1;
        var itemCheckedCounter = itemData.Item2;
        var itemList = itemData.Item3;
    
        var checklistDict = GetChecklistRestrictions(parentFolder, itemCounter,
            itemCheckedCounter, priorityCounter);
    
        checklistDict.Add("color", color);
        checklistDict.Add("itemList", itemList);
        checklistDict.Add("checklistCounter", checklistCounter);
    
        return GetChecklistLayout(checklistCount, checklistLayoutDict);
    }
    

    如您所见,我几乎在一个页面加载中运行了两次清单。我不想这样做。如果有人有更好的想法来提高效率,请告诉我。

    更新: 上述解决方案(即使只发布了部分代码)解决了我的问题,但是我决定只在视图上捕获清单并将其添加到模型中,然后在部分中使用该模型(pageModel.Checklists),因此我实际上并没有使用 Linq 两次抓取清单。我仍然需要重复检查清单两次,但我没有两次获取值。所以更多的是 hack,但也许我以后会继续寻找一种方法来简化它。

    【讨论】:

      猜你喜欢
      • 2018-05-31
      • 2013-04-16
      • 2016-08-19
      • 1970-01-01
      • 2021-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多