在先前加载的剃刀局部视图中更新模型值

时间:2017-08-16 13:47:19

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

我有一个视图,在视图渲染时加载一组模块(我们会说其他部分视图)。

所以在主视图中这样想一下:

<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<string, ChecklistItem> 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之前加载, ChecklistPriorityLevelModule1的值始终从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>
}

模型中的相对代码只是常规获取,此时设置:

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

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

所以我的问题是如何更改此模型的值以触发已加载的其他模块(部分视图)的更改?

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

1 个答案:

答案 0 :(得分:0)

修复我自己的问题(但我仍然希望看到如何处理)

因此,对于我的特定问题,我决定在加载任何模块之前强制设置模型的值。我的应用程序的工作方式,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两次获取清单。我仍然需要两次遍历清单,但我没有抓住两次值。所以更多的是黑客,但也许我会在以后找到一种方法来简化这个。