跨页面携带值以用作路由参数的首选方式

Posted

技术标签:

【中文标题】跨页面携带值以用作路由参数的首选方式【英文标题】:Preferred way to carry a value across pages to use as route parameter 【发布时间】:2022-01-06 11:33:05 【问题描述】:

我想要一个选择列表,它将列出表查询中的项目供用户选择。 这是用

呈现的
 Options = _context.BranchAssignment
            .Where(a => a.ColleagueID == UserColleague)
            .IgnoreQueryFilters()
            .OrderBy(a => a.Branch.BranchNumber)
            .Select(a => 
             new SelectListItem
             
                 Value = a.BranchID.ToString(),
                 Text = a.Branch.BranchName
             )                                    
             .ToList();
<form id="assignedBranch" method="post">
            <div class="row">
                <select asp-for="BranchSelect" asp-items="Model.Options" onchange="this.form.submit();"></select>
            </div>
        </form>    

如您所见,这是一个非常简单的表格。我目前正在开发的解决方案应该是 onFormSubmit,采用选中的选项,将其设置为 cookie 值,然后如果用户导航到另一个页面,我可以为选择列表设置选中的选项。

我仍在调试这个问题,我想知道是否有更好的解决方案。理想情况下,我希望这个选择列表编写一次并显示在 _layout 导航栏中,但我相信您无法从视图组件中读取(我的最后一次尝试)来获取所选值以用作 OnGet 中的路由参数。

如果您想象用户转到页面 A 并选择列表选择的项目是选项 2,那么我想通过 onGet 加载 webaddress.com/PageA/option2,因为路由将设置为选项 2

如果他们随后转到页面 B,则选择列表将呈现并记住他们之前的 option2 选项,因此它将加载 webaddress.com/PageB/option2 以及他们是否可以更改为例如option3 和 OnFormSubmit webaddress.com/PageB/option3 之后将加载。

如果我以错误的方式处理此问题,我将感谢推动首选流程。

【问题讨论】:

不建议使用route传值,可能会造成一些路由冲突,使用cookie即可。 @XinranShen 我的问题可能不清楚,但我不打算在路由中传递任何值,cookie 是我传递值的可能选项,但路由将在 onGet 中设置基于 cookie 值的页面。 【参考方案1】:

我建议你使用cookie来跨页面携带值,而不是使用路由参数。

我分两步实现:

首先,给&lt;select&gt;添加一个Onchange事件,当你选择一个选项时,Onchange事件会设置一个cookie来保存你选择的值。

其次,当您加载其他页面时,&lt;select&gt; 会读取 cookie 以显示您之前的选择。

这是我的代码:

DropDown List in _layout .cshtml

<li>
    <select id="fruit" onchange="save(this.value)">
       <option value=0>apple</option>
       <option value=1>pear</option>
       <option value=2>watermelon</option>
       <option value=3>cherry</option>
     </select>
</li>

javascript in _layout .cshtml

<script>
         //....................set Cookie............
       var saveclass = null;

        function save(cookieValue)
        
            var sel = document.getElementById('fruit');
            saveclass = saveclass ? saveclass : document.body.className;
            document.body.className = saveclass + ' ' + sel.value;
            setCookie('theme', cookieValue, 365);
        

        function setCookie(cookieName, cookieValue, nDays)
        
           

            var today = new Date();
            var expire = new Date();

            if (nDays==null || nDays==0)
                nDays=1;

            expire.setTime(today.getTime() + 3600000*24*nDays);
            document.cookie = cookieName+"="+escape(cookieValue) + ";expires="+expire.toGMTString() +";path=/";
        
        //......................read Cookie.............
         document.addEventListener('DOMContentLoaded', function() 
        
            var themeSelect = document.getElementById('fruit');
            var selectedTheme = readCookie('theme');

            themeSelect.value = selectedTheme;
            saveclass = saveclass ? saveclass : document.body.className;
            document.body.className = saveclass + ' ' + selectedTheme;
        );

        function readCookie(name) 
        
            var nameEQ = name + "=";
            var ca = document.cookie.split(';');
            for(var i = 0; i < ca.length; i++) 
            
                var c = ca[i];
                while (c.charAt(0) == ' ') c = c.substring(1, c.length);
                if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
            
            return null;
              
 </script>

然后你可以在其他页面上获取相同的选项

是的,你是对的。当我从 setCookie 函数中删除 days 组件时,cookie 只会在会话存在时存在。

【讨论】:

感谢详细的回答。但是,我确实想澄清我的问题,为了使用模型绑定,我的列表是从附加的页面模型生成的。完全消除模型绑定并在 _layout 中采用视图组件是否为 Razor 页面解决方案提供了最佳选择? 作为后续,您能否确认如果我从您的 setCookie 函数中删除 days 组件,该 cookie 将仅在会话存在时才存在。这很重要,也是 ASP.Net HTTPCookie 类的好处之一 我写这些硬代码只是为了测试方便,你也可以使用模型绑定来显示这些数据。我改变了我的答案,当我从 setCookie 函数中删除 days 组件时,你可以看到只要会话存在,cookie 就会存在 嗨@Xinran Shen,我将接受您的回答,因为它确实适用于硬编码列表。如果您说模型绑定将起作用,我将不胜感激。据我了解,在 _layout 文件中获取动态填充的选择列表的唯一方法是通过视图组件,但我看不到任何通过模型绑定的方法。 感谢您接受我的回答。在MVC中,可以在controller中使用ViewData['xx']=new SelectList(xx),在view中使用asp-items="xxx"来实现模型绑定。但是,在 Razor 页面中,在_layout 中实现模型绑定非常复杂,所以,如果_layout 页面中的代码不经常更改,我建议您直接使用硬编码。

以上是关于跨页面携带值以用作路由参数的首选方式的主要内容,如果未能解决你的问题,请参考以下文章

VUE学习--路由跳转方式||路由跳转携带参数方式||目标路由接受参数方式

详解vue 路由跳转四种方式 (带参数)

vue路由跳转页面的几种方式及其区别

实现接口参数为空时不传参,刷新页面时参数重置问题

Android系统路由之-scheme实现网页链接携带参数跳转到Activity

将 xsl:apply-templates 转换为字符串值以用作 if 参数