ExtJS 4 MVC视图和子/子控制器困难的多个实例
我在ExtJS 4中遇到了MVC模式的问题。至少,我想我有。 在与这个问题接触过多个人,并在Sencha论坛上发表过无数次后,我现在正在转向更广泛的观众,希望得到一个灯泡或确认。
问题
您的应用程序可以打开许多不同的视图,其中一些视图本身就是迷你应用程序。 此外,用户可能希望打开一个视图的多个并发副本。
这个应用程序是一个单页面的客户端JavaScript应用程序。
ExtJS 4 MVC模型期望您在应用程序类中定义所有控制器。 这些控制器随后在应用程序加载时初始化。 控制器跟踪视图,模型和商店。
当多次初始化控制器A(比如说创建一个视图的多个副本)时,最终会引用两个引用相同数据存储的视图,并在功能上将重复事件发送到Application事件总线。
我通过向组件和控制器添加新的原型方法来重构我的应用程序,以允许a)子控制器(我的一些控制器变得非常大)以及b)专门为它们的视图定义商店。 模型仍然可以在控制器上定义,只是为了方便处理程序使用,如果您需要执行类似于从服务器获取记录的操作。
题
我对MVC的理解会让我相信模型更直接与View相关,而不是Controller。 我鼓励ExtJS 4决定将控制器的存储(我认为可以看作是更经典的模型的包装),以鼓励重新使用已加载的数据,并优化远离同一类的许多副本实例化。 然而,在我看来,如果一个人打算让许多用户可以看到的视图实例,就不能这样做。 在我看来,拥有很多实例是面向对象框架中的一个重要选项,因此我反对这一趋势并在某些基础类实现了原型。 (谢谢Ext.implement!)。
是否有任何方法可以使用开箱即用的MVC类并使用提供的setters,getters等来将多个并发的视图不同数据实例加载到它们中?
我遇到了类似的问题:
考虑一个CRM类型应用程序的tabpanel,它为每个客户端打开一个视图的新实例。 并且说标签视图包含3或4个行编辑网格面板,用于与与该客户端相关的不同数据集合进行交互。
我提出的解决方案是基于Sencha论坛的这个解决方案。 在坚果壳中,几乎所有从视图派发的事件都包含对视图本身的引用。 我的控制器控制功能中的处理程序都使用这些来获取对正确视图实例的引用。
为了处理为此需要的同一商店的多个实例,我从这篇文章中考虑了这一点:
对于视图上的Store实例或全局实例...取决于需求。 如果你打算使用全球化,那么把它变成全球化的。 如果你只是在视图上需要它,然后把它放在视图上。 MVC不是一个法律,你可以改变它来适应你的需求。 从技术上讲,MVC的控制器部分被认为是视图和模型部分之间的中间人,但有时候这并不需要。 我在95%的时间内创建了商店。 我给你举个例子......
如果您有产品商店,则可能只需将该商店引用到您的网格中即可。 这通常不是应用程序的其他部分所必需的。 但是,如果您有商店来加载国家/地区,我经常在全球范围内使用它,因此我只需加载一次,然后可以在多个视图中设置/使用该商店。
所以我只是在视图的initComponent方法内创建了与视图实例相关的所需商店。 该应用程序确实有一些全球商店,我遵循MVC建议作为商店类创建。 它很好地封装视图中的视图实例存储。 然后我只需要一个控制器实例。
为了明确回答你的问题,目前没有ExtJS官方建议或配置来处理使用相同商店构造函数的同一视图的多个实例。 我花了一些时间寻找类似的东西,我发现最好的是来自其论坛版主之一的这一建议。
无论您拥有多少个视图/模型,我认为您不需要超过1个控制器实例。 在这里查看功能示例:
http://whatisextjs.com/extjs-4-extension/fieldset-w-dynamic-controls-7
这可以很容易地完成。 你需要遵循一些规则:
在应用程序启动时加载控制器。 不要卸载它们。 不要担心内存或时间,即使对于数百个控制器,只要您最小化和连接您的js,它就非常小。
切勿使用控制器的参考或视图属性。 您将使用控制器的一个实例,但使用多个视图实例,因此您不需要引用视图。
只能在控制器中使用事件监听器。 你只会听你的意见事件。 您可以通过处理程序中的“cmp”参数始终获取对事件处理程序中视图的(临时)引用。
要“启动”一个视图,创建它并将其添加到另一个视图。 摧毁它,摧毁它。 您不使用控制器来启动视图。 您可以使用afterrender和beforedestroy控制器中的事件来添加逻辑。
上一篇: ExtJS 4 MVC multiple instances of views and sub/child controller difficulties