JavaScript MVC:视图如何通知控制器

Posted

技术标签:

【中文标题】JavaScript MVC:视图如何通知控制器【英文标题】:JavaScript MVC: how do views notify the controller 【发布时间】:2012-02-02 00:01:31 【问题描述】:

如果我在 javascript 中遵循粗略的 MVC 模式,视图(例如 button 元素)通知控制器的最佳方式是什么?

button 是否应该触发控制器必须监听的事件?或者,button 是否应该直接调用控制器函数?或者控制器应该将事件分配给视图?

感谢您的任何意见!

【问题讨论】:

控制器监听输入。这意味着控制器会监听来自 DOM 节点的事件。 @Raynos:您的意思是视图为 dom 元素分配了一个 onclick,并在该 onclick 内部触发一个控制器必须订阅的事件?谢谢! 不,视图与控制器没有业务往来。控制器以某种方式获取 dom 节点上的句柄并附加处理程序本身。 @Raynos 太棒了!感谢您的解释。如果您将此作为答案发布,我会接受。 【参考方案1】:

有很多方法可以做到这一点。这是一种方法。

var app = new App();

function App() 
  var model = new Model();
  var view = new View();
  var controller = new Controller(view, model);


function Controller(view, model) 
  view.addActionListener(function() 
    alert("on activate");
  );


function View() 
  var self = this;
  $("button").onclick = function() 
    self.listener();
  


View.prototype.addActionListener = function(listener) 
  this.listener = listener;

【讨论】:

【参考方案2】:

我会说 View 应该捕获按钮触发的事件并触发自己的事件,该事件将由 控制器 处理。

让我解释一下:

@raynos 写道:

控制器监听输入。这意味着控制器监听事件 来自 DOM 节点

就个人而言,尽管我同意第一个陈述,但我不喜欢这种解释。

遵循此声明意味着控制器必须知道 UI 中的每个按钮/文本字段/元素及其 ID/选择器。

我更喜欢让 View 触发语义事件,例如“languageSelected”或“searchRequested”,并将相关数据添加到事件中。

所以一个典型的流程是当用户点击按钮时,视图呈现一些 UI(假设它有一个搜索框和一个按钮) - View 处理事件并触发它自己的“searchRequested”事件。此事件由 Controller 处理,该控制器将调用 Model 并要求它执行搜索。完成后,Model 将触发“searchResultsUpdated” evnet,该 evnet 将由 View 处理,使其显示结果。

如果您现在选择更改应用的设计以显示搜索词链接而不是搜索框和按钮(或者即使您当时并排 - 或在不同的屏幕上),您唯一需要更改的就是是视图

技术说明: 如果使用 JQuery 并假设您的视图是一个 javascript 对象,您可以使用

$(view).triggerHandler( 
   $.Event('eventName','object:'with','more':'event','related':'data')  
);

触发事件

还有

$(view).on('eventName',handler); 

监听和处理事件。

【讨论】:

IMO,这绝对是一种更好的方法。控制器不应该监听按钮点击之类的东西,它应该监听语义事件/请求的功能。最终用户如何启动该功能可能在两个不同的视图之间有所不同(人们经常忘记 MVC 的要点之一是能够拥有多个视图而无需更改模型或控制器)。【参考方案3】:

有趣的问题。我认为这在很大程度上取决于您的情况、示例的复杂性以及您使用的特定 JavaScript 模式。

如果您所说的按钮只是一个 html 元素,这可能是一种简单的方法:

var MyController = function() 

    this.particularMethod = function()  
        // update model
    

    // Using jquery
    var button = $("#myButton");
    button.click( function()  myController.particularMethod()  )

或者,如果您的 button 是您创建的对象或模块,您可以设置回调:

var Button = function(selector, clickFunction) 
    // Using jquery
    $(selector).click(clickFunction)
    ...


var MyController = function() 

    this.particularMethod = function()  
        // update model
    

    var button = new Button("#myButton", this.particularMethod);
    ...

不幸的是,琐碎的例子并不能真正说明不同方法的好处!

【讨论】:

以上是关于JavaScript MVC:视图如何通知控制器的主要内容,如果未能解决你的问题,请参考以下文章

干货理解理解javascript中实现MVC的原理

MVC 中的模型到视图通信?

如何在推送通知中导航到另一个视图控制器

如何将视图中的 javascript 代码中的对象列表传递给控制器​​中的操作方法

MVC如何从视图调用控制器中的动作以返回值

设计:如何通知控制器有关跨应用程序的数据修改