将任意数据从局部视图传递到布局视图

Posted

技术标签:

【中文标题】将任意数据从局部视图传递到布局视图【英文标题】:Pass arbitrary data from a partial view to the layout view 【发布时间】:2012-04-17 13:39:22 【问题描述】:

更新:似乎我试图在 partial 视图中设置 ViewBag 内容,而不是在 plain 视图中,MVC3 使它非常很容易做到这一点。我仍然对为什么它不适用于局部视图感兴趣,即为什么视图包不与局部视图共享。

我正在尝试使用 ViewData/ViewBag 将部分数据从部分视图传递到布局视图

// Used in the partial view
public static void RequireAssets(this htmlHelper helper, params Asset[] assets)

    var alreadyRequired = helper.ViewData["RequiredAssets"] as List<Asset>;
    if (alreadyRequired == null)
    
        alreadyRequired = new List<Asset>();            
        helper.ViewData.Add("RequiredAssets", alreadyRequired);
    

    foreach (var asset in assets.Where(anAsset => !alreadyRequired.Contains(anAsset)))
        alreadyRequired.Add(asset);


// Used in the layout view
public static MvcHtmlString RenderAssetStyles(this HtmlHelper helper)

    var requiredAssets = helper.ViewData["RequiredAssets"] as List<Asset>;
    return requiredAssets == null ? null : GetStyleSheets(requiredAssets.Select(e => new StyleSheet(e)).ToArray());


public static MvcHtmlString RenderAssetScripts(this HtmlHelper helper)

    var requiredAssets = helper.ViewData["RequiredAssets"] as List<Asset>;
    return requiredAssets == null ? null : GetScripts(requiredAssets.Select(e => new Script(e)).ToArray());

问题是当在布局视图中触发 RenderAssetStyles/Scripts 时,ViewData 不包含键“RequiredAssets”

用法

_Layout.cshtml:

<title>@ViewBag.Title</title>    
@Html.RenderAssetStyles()

PartialView.cshtml:

@ 
    Html.RequireAssets(Assets.Grid, Assets.FileUpload); 

【问题讨论】:

【参考方案1】:

我无法重现这一点。我不得不简化你的代码并做出一些假设。但以下对我来说效果很好。

_Layout.cshtml

@using MyProject.Helpers
<title>@ViewBag.Title</title>    
@Html.RenderAssetStyles()
@Html.RenderAssetScripts()
@RenderBody()

View.cshtml

@using MyProject.Helpers
@ 
    ViewBag.Title = "View";
    Html.RequireAssets(Asset.Grid, Asset.FileUpload);
    Layout = "~/Views/Shared/_Layout.cshtml";

Helpers.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MyProject.Helpers

    public enum Asset
    
        Grid=1,
        FileUpload=2
    
    public static class Helper
    

        public static void RequireAssets(this HtmlHelper helper, params Asset[] assets)
        
            var alreadyRequired = helper.ViewData["RequiredAssets"] as List<Asset>;
            if (alreadyRequired == null)
            
                alreadyRequired = new List<Asset>();
                helper.ViewData.Add("RequiredAssets", alreadyRequired);
            

            foreach (var asset in assets.Where(anAsset => !alreadyRequired.Contains(anAsset)))
                alreadyRequired.Add(asset);
        

        // Used in the layout view
        public static MvcHtmlString RenderAssetStyles(this HtmlHelper helper)
        
            var requiredAssets = helper.ViewData["RequiredAssets"] as List<Asset>;
            return requiredAssets == null ? null : MvcHtmlString.Create("Test Style");
        

        public static MvcHtmlString RenderAssetScripts(this HtmlHelper helper)
        
            var requiredAssets = helper.ViewData["RequiredAssets"] as List<Asset>;
            return requiredAssets == null ? null : MvcHtmlString.Create("Test Script");
        
    


【讨论】:

我会尝试打破 RequireAssets 帮助程序,然后每个 MvcHtmlStrings 来检查它们被调用的顺序。我可以实现的唯一“复制”是将所有内容都放在一个 .cshtml 中,在这种情况下,如果您在 RenderAssetStyles/RenderAssetScripts 之后调用了 RequireAssets,那么在需要它们的调用之前,您将不会设置任何资产。 看来我将视图呈现为部分视图,我已经更新了问题。 ***.com/questions/4974027/… 可能会有所帮助【参考方案2】:

认为你做错了什么。无法复制你的努力。尝试检查 - 您的视图是否使用此布局。一切都可以尝试创建可重现的简单示例。

【讨论】:

看来我将视图呈现为部分视图,我已经更新了问题。

以上是关于将任意数据从局部视图传递到布局视图的主要内容,如果未能解决你的问题,请参考以下文章

将数据从局部视图传递到父视图

将值从部分值传递到 mvc 中的布局视图

将局部变量从控制器传递到视图

将一个模型从局部视图传递到父视图,并将另一个模型绑定到同一个父视图

从控制器到视图的数据传递

SwiftUI 中如何获取任意视图触摸位置(全局或局部)的坐标