【问题标题】:Decouple controller and view in ExtJs在 ExtJs 中解耦控制器和视图
【发布时间】:2012-03-12 06:13:18
【问题描述】:

我正在研究 ExtJs,并试图找到组织我未来项目的最佳方式。 我从 ExtJs MVC 教程开始http://docs.sencha.com/ext-js/4-0/#!/guide/application_architecture

我不喜欢这个架构中的一些东西: 控制器“了解”视图小部件并以这种方式添加事件侦听器

this.control({
            'viewport > userlist':{
                itemdblclick:this.editUser
            },
            'useredit button[action=save]':{
                click:this.updateUser
            }
        });

我们正在启动一个包含 500 多个表单的大型项目。 我相信在这么大的项目中,这种方法会造成很大的混乱。 有没有办法解耦控制器和视图?

例如,在 GWT 中,他们使用 MVP 模式,其中 Presenter 不知道视图的内部结构 并通过“显示”界面与视图交互。 我知道,Javascript 没有接口,但可能有一些方法可以在 Extjs 中模拟它们。

我希望我的控制器是这样的:

editButton = viewInterface.getEditButton();
editButton.on('click', function(btn, e, eOpts) {
    eventBus.fireEvent(editUserEvent);
});

有可能吗?

【问题讨论】:

    标签: architecture extjs extjs4 mvp


    【解决方案1】:

    绝对有可能。在您的视图中创建一个方法 getEditButton 并返回您想要的任何内容。这不是问题。

    然而,我的 2c 用于分离视图和控制器。我目前也在做一个相当大的项目。可能没有你的那么大,但我们将拥有大约 100 多个视图/控制器。

    我尝试使用两个主要的经验法则来构建这个项目:

    1. 如果我有一些通用逻辑,无论是在视图中还是在控制器中 - 我创建基类并将此逻辑移到那里。所以稍后 - 我只是扩展它,以便子视图/控制器获得相同的功能。

    2. 我将与应用程序业务逻辑无关的代码留在视图类中 - 例如,如果我有一个网格并且需要添加特殊代码来选择网格中的所有记录,或者显示记录数和状态栏内网格中选定记录的数量 - 此代码用于查看类。因此控制器对这些“简单”任务一无所知,只关注应用程序的业务逻辑。

    【讨论】:

    • 谢谢。你能谈谈事件总线吗? ExtJs4 中是否有任何实现?
    • 我想支持这种方法。让控制器尽可能少地了解视图,让视图生成像 fireEvent.editUser(user) 这样的高级事件,并让控制器监听这个事件。
    【解决方案2】:

    在视图中包含逻辑确实违背了 MVP 模式的目的。我建议查看deftjs,因为它使组件查询更清晰。由于大多数用户操作都在诸如按钮之类的控件上,因此我给他们一个操作并查找该独特操作,例如登录。

     control: {
        submitButton: {
            selector: 'button[action=login]',
            listeners: {'click': 'login'}
        }
     }
    

    上面的问题是它仍然将控制器绑定到视图组件,按钮,因为它引用了它的类型。您可以用 id 替换它,但我也不喜欢它。我相信获得此功能的最佳方法是为 deftjs 做出贡献以拥有更通用的事件模型,他们可能在路线图上拥有它,因为它们基于 RobotLegs 等项目。如果很快没有人提供此功能,我可能会尝试一下。

    最后但并非最不重要的一点是,如果您发现需要向组件添加逻辑,最好扩展该组件并与您的视图分开测试它。

    【讨论】:

    • 谢谢。为什么我们必须在视图中添加任何逻辑?我更喜欢把它放在控制器(演示者)中。而且我真的不喜欢“控制”声明,因为它是全球性的。我更喜欢这样做:this.editView.getSaveButton().on('click', this.updateVehicle, this);
    • 这就是为什么我建议 deftJS 它改变了控制语句的工作方式。它是本地的,而且不那么丑陋。在我上面的示例中,视图中没有代码,它会在演示者中。
    【解决方案3】:

    我宁愿让视图触发有意义的事件,例如使用 fireEvent 进行“编辑”。

    控制器将知道视图并可以监视视图上的“编辑”事件。

    查看:

    this.on(this.btnEdit, 'click', function(){ this.fireEvent('edit');},this);
    

    控制器:

    this.mon(this.viewInstance, 'edit', this.doEdit, this);
    

    这种方式控制器不知道视图内部。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      • 2011-02-05
      • 2015-12-17
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多