我有一个完整的页面表组件(自定义,具有列过滤器、排序、动态加载、"无限"滚动等(,然后用户单击";编辑";操作,则导航到编辑项目页面。再次,整页。这是一个要求,它在视觉上应该是单独的页面。2个原因:用户做的一项大任务是搜索,表越大,数据越多越好。第二项任务是更新一些记录。单个记录是一个非常非常复杂的数据集,它确实需要尽可能多的屏幕空间。
问题是,当用户编辑完记录后,应用程序会导航到上一页,但表会重置,并具有默认的过滤、排序和滚动位置。
好吧,我可以从表组件中提取数据,并将其存储在";伪会话";服务数据。这样做的问题是,我必须向表组件-加载/保存状态方法添加大量代码。确实有很多工作要做(针对每个列过滤器元素,然后针对列过滤器行(。
但有一个更简单的方法。不使用单独的页面,我可以伪造它。将表和行编辑表单放在同一个页面上,然后用JS/CSS隐藏一个部分。这应该有效,但IDK,对我来说,这似乎是一个丑陋的黑客。你渲染两个部分,展示一个。
顺便说一句,如果您在.razor
文件中隐藏服务器端的组件,然后再次显示它,它就会重置。将调用构造函数,所有参数都设置为默认的初始值。
有没有一种方法可以在服务器端隐藏渲染的片段,然后显示它,而不会导致Blazor重新初始化它?
或者一个";背面";函数,显示与导航发生前完全相同状态的最后一页?
更新:我刚刚测试了隐藏选项。发挥魅力。方法如下:
<div style="@("display: " + (CurrentView == ViewOptions.List ? "block" : "none"))">
@* My list view here... *@
</div>
@if (CurrentView == ViewOptions.Edit) {
@* My edit entry view here... *@
}
其中ViewOptions
只是包含可能视图的enum
。CurrentView
属于ViewOptions
类型。当CurrentView
设置为List
时,第一部分可见,第二部分根本不渲染。当它发生更改时,第一部分将被隐藏(但不会被销毁(,第二部分将被初始化和渲染。由于我的表单已经作为单独的组件完成,所以它们将行标识符作为参数,并触发自己的事件,允许在用户完成操作后将CurrentView
切换回列表。所以我们基本上在一个页面上有两个虚拟页面。这是一个棘手的解决方案,但它有效。我已经在30分钟内完成了这项工作,而不是花几个小时为DataTable
组件添加加载/保存功能。
不过,也许还有更好的方法?或者它可能是最优的?喜欢我们有页面(彼此直接无关(和。。。子页面在视觉上是分开的,但在逻辑上与其父页面直接相关。
这给了我一个想法。。。如果我制作了一个名为Subpage
的组件呢?:(Blazor中已经存在一个名为Page
的组件。因此,它希望完成页面和子页面的整个概念。当页面没有直接关联时,导航";背面";转到上一页。甚至维护不相关页面的状态。但这个子页面是直接相关的。其内容取决于父页面的状态。IDK,也许走那条路太疯狂了;(
TL;DR:我认为,你走的是正确的低成本路线。
";正确的";(或者更确切地说,完整、完整(的方法是实现所有的状态存储(实现、公开、处理事件、将数据存储在浏览器本地存储或应用程序状态等地方(。正如你所发现的,用真正的if
切换一个组件会重置它-这就是应用程序状态的来源-你可以保持事件中的状态与更改它相关,然后下次组件初始化时,它读取该状态。但你必须自己完成这一切,这是大量的工作。
因此,有两种更简单的解决方案:
-
如您所见,使用CSS隐藏旧内容(如果需要(,并在同一页面上显示新内容。如果您在某种窗口/对话框中显示它,则可能根本不必隐藏旧内容。
-
或者,使用某人编写的组件,该组件已经内置了这些状态功能,因此您可以直接使用它们。这是一个我知道的商业广告。