以这种方式实现单页应用程序是不是一种糟糕的做法

本文关键字:一种 方式 实现 单页 是不是 应用程序 | 更新日期: 2023-09-27 18:28:59

好的,

所以我创建了这个web应用程序,它被设计成一个单页应用程序。有一个菜单,它只在一个更新面板中加载各种用户控件(设计为表单)中的一个(清除控件、加载新控件等)。用户执行任何输入、单击保存、删除等操作。在这些用户控件中,有几个数据绑定和内部依赖控件,这是我将它们加载到更新面板中的主要原因。

现在,我遇到了这样的问题:当用户选择一个新菜单,然后更改数据绑定控件的值时,该控件仅在第一次回发时丢失其值。我很确定这是由于清除了用户控件所在的容器,因为我已经尝试过清除和加载常规面板,但我也会遇到完全相同的问题。由于在我的情况下使用(!IsPostBack)不起作用,我只是创建了一个布尔会话变量,以便在页面和用户控件之间执行数据绑定方面的相同逻辑。为了进一步测试我的问题,我将应用程序更改为多页应用程序,问题消失了;值在回发时保留。

因此,为了达到我的初衷,正如我所看到的使用多个页面的功能;我想,在单页版本中,如果我只是在代码中添加"Server.Transfer(defaultpage.aspx)",我将保留从多页方法中获得的功能,同时让用户保持在同一页上。它非常有效。没有数据丢失,它正常工作。这味道不好吗?所有用户功能和职责总是在一个页面上执行,导航对它们没有任何作用。

我只是担心,从本质上刷新页面只是一种糟糕的做法或技巧,但它对应用程序的目的是有效的,并且在不必要的时候可以节省创建2-3打页面的费用。我读过一些帖子,其中有人会这样做只是为了清除结果,或者一些次要的事情,但仅此而已。

如果这是一种糟糕的做法(或者即使不是),也许有人能解决第一次回发价值损失的问题吗?我在数据绑定的主控件、页面控件、用户控件和子控件上启用了enableviewstate=true和viewstatemode=enabled。提前感谢您的任何意见。

以这种方式实现单页应用程序是不是一种糟糕的做法

这种做法在未来会导致很多问题。我不喜欢这个

所以,如果有人遇到同样的问题,并且没有合法的解决方法,我前几天回来解决这个问题时"想出"了一个。

第一个回发问题似乎源于容器控件(占位符、面板、更新面板等)的清除和重新填充。由于我让用户单击菜单项,然后清除用户控件并将其加载到容器中,因此回发时引用的用户控件与加载的新用户控件不同。请耐心听我如何描述这种情况。。。

上次加载的用户控件在菜单单击事件触发之前的初始菜单单击中被引用,然后容器被清除,新的用户控件从菜单单击事件中加载。当容器中没有加载控件(初始启动)时,不会发生这种情况。由于用户控件是动态添加的,我有一个方法可以重新加载当前加载的用户控件,它被放置在Page_Init中。此事件,连同PreInit、_Load,都是控制前激发事件,是我的问题的原因。根据更多的经验,修复方法是将if语句添加到usercontrol加载方法和Page_Init(或任何有加载方法的地方)中,以确定导致回发的原因。因为,我只想让用户点击菜单项在众多任务中移动,我只是确保如果菜单项点击导致了回发,那么,不要在Init中运行加载方法,但是,任何其他导致回发的方法(对我来说,仅在用户控件内),Init中的加载方法只会在那时触发。

此外,if语句在加载方法中是必要的,以确保新添加的usercontrols中的所有控件都包含默认值/空值,基本上是您希望用户在控件首次显示时看到的默认值,在我的情况下,我有:

if (Page.Request.Params["_EVENTTARGET"].Contains("Menu1") == true) 
{ 
uc.Clear(null, null);
uc.SetBoundControls();
}

)

希望这能帮助其他人,或者激发人们对更好解决方案的思考。

是的,这是一种糟糕的做法。WebForms的状态问题随着UI复杂性的增加而不断恶化。

我使用一个类来持久化SPAUI状态,该类被序列化为XML并以纯文本形式保存到数据库中。我使用URL中的GUID作为会话密钥(但您可以有用户id或ASP.NET会话id,或其他任何信息)来检索每个请求的状态信息,这消除了用户刷新页面时管理状态或丢失数据的任何问题。

这样做还有一个额外的好处,即允许您用单元测试来覆盖逻辑UI,而不会被web层细节所困扰——这对复杂的工作流来说很好。

不过,如果你尝试这样做,我建议你考虑转向MVC,并使用简单的旧Post和Redirect;当您希望允许后退按钮时,请将hash标记添加到重定向响应中。