JavaScriptMVC之控制器监听事件

控制器安装和卸载事件句柄非常容易。卸载事件句柄对于防止内存泄漏非常重要。

自动绑定

当一个新的控制器创建后,控制器原型方法那些是事件句柄。它会把使用控制器的事件委托功能把这些函数绑定控制器上。 当这个控制器销毁(或者对应的元素从页面上删除),控制器将自动卸载它的事件句柄。 例如:以下控制器的每个函数将自动绑定:

 

$.Controller("Crazy",{

  // listens to all clicks on this element
  "click" : function(el, ev){},

  // listens to all mouseovers on 
  // li elements withing this controller
  "li mouseover" : function(el, ev){}

  // listens to the window being resized
  "{window} resize" : function(window, ev){}
}) 

控制器通过函数名加空间,标准的DOM事件名,Jquery专用事件名(请查看$.event.special)。

一般而言,除了没有选择器和事件不在Jquery专用事件内,控制器都会知道自动绑定事件句柄。

如果遇到上面的情况,你就需要添加这个函数名到控制器的静态listensTo属性里。 例如:

 $.Controller("MyShow",{
   listensTo: ["show"]
 },{
   show: function( el, ev ) {
     el.show();
   }
 })
 $('.show').my_show().trigger("show"); 

 回调函数的传递参数

事件句柄绑定是控制器在元素上回调且把事件当成参数传递过来。this引用指的是控制器实例。例如:

 

$.Controller("Tabs",{

  // li - the list element that was clicked
  // ev - the click event
  "li click" : function(li, ev){
     this.tab(li).hide()
  },
  tab : function(li){
    return $(li.find("a").attr("href"))
  }
}) 

 模板匹配事件绑定

模板匹配事件句柄是控制器一个非常强大的特性。你可以把事件名,选择器,或者事件的根元素参数化。 模板匹配事件名称和选择器 常常,你想要创建一个配件行为配置。一个通俗的例子是菜单显示子菜单事件(例如:点击或者鼠标进入)。 以下控制器让你配置当一个菜单想显示子菜单时的事件。 以下创建2个按钮。

 

$.Controller("Menu",{
  "li {showEvent}" : function(el){
    el.children('ul').show()
  }
})

$("#clickMe").menu({showEvent : "click"});
$("#touchMe").menu({showEvent : "mouseenter"});

 $.Controller使用双括号来替换控制器中的options对应的值。这就意味着我们可以很容易实现一个默认的showEvent值来代替上面的作法, 而且创建菜单时,不需要再提供一个值了。例如:

 

$.Controller("Menu",
{
  defaults : {
    showEvent : "click"
  }
},
{
  "li {showEvent}" : function(el){
    el.children('ul').show()
  }
});

$("#clickMe").menu(); //defaults to using click

 有时,我们可能想去配置我们的配件去使用不同的元素。下面是把菜单子菜单显示事件绑定到按钮上。

$.Controller("Menu",{
  "{button} {showEvent}" : function(el){
    el.children('ul').show()
  }
})

$('#buttonMenu').menu({button: "button"});

 模板匹配根元素

最后,控制器的事件句柄绑定到控制器元素外的对象上。 以下是监听窗口的点击事件:

$.Controller("HideOnClick",{
  "{window} click" : function(){
    this.element.hide()
  }
})

如下是监听Todos的创建事件:

$.Controller("NewTodos",{
  "{App.Models.Todo} created" : function(Todo, ev, newTodo){
    this.element.append("newTodos.ejs", newTodo)
  }
});

 但是上面代码只能监听Todo Model的新建Todos的动作。我们也可以把它修改为可配置的:

$.Controller("Newbie",{
  "{model} created" : function(Model, ev, newItem){
    this.element.append(this.options.view, newItem)
  }
});

$('#newItems').newbie({
  model: App.Models.Todo,
  view: "newTodos.ejs"
}) 

 那么模板匹配到底是如何实现的呢?

当查找一个值去替换双括号,控制器首先想找在options中的项,如果没有查找到,再去Window对象中查找。这里不是使用eval去查找对象。 代替它的是使用了jQuery.String.getObject,详细请看语言助手(Language helpers)下的$.String.getObject,在这里不详细介绍。

 

预订OpenAjax信息和自定义绑定

使用jquery/controller/subscribe插件允许控制器监听OpenAjax.hub信息。 其实这个功能很像我们Java中的订阅模式,我们只需要预订对应事件,当事件发生时,会通知所有的订阅者。 例如:

steal('jquery/controller/subscribe').then(function(){
	//这个控制器既是订阅者,又是发布者
    $.Controller('subscribeTest',{
        onDocument: false
    },
    {
        "#subscribe1 click": function(el, ev){
            ev.stopPropagation();
			//点击按钮,向所有订阅者发布
            this.publish("oaSubscribe1", {"params":"Hola Mundo"});		
        },
		//订阅者收到发布的处理函数
        "oaSubscribe1 subscribe": function(called, data){
            alert("subscribeTest " + data.params + " : " + this.Class.shortName);
        }
    });
    
	//这个控制器只是订阅者
	$.Controller('subscribeTest1',{
        onDocument: false
    },
    {	
		//订阅者2收到发布的处理函数
        "oaSubscribe1 subscribe": function(called, data){
            alert("subscribeTest1 " + data.params + " : " + this.Class.shortName);
        }
    });
	
    var subscribeController = new subscribeTest($("#testSubscribe")[0]);
    var subscribeController1 = new subscribeTest1($("#subscribe2"));
    $("#off").bind("click",function(){
       subscribeController.destroy(); 
	   subscribeController1.destroy(); 
    })
});

 

 手动绑定事件

控制器的原型bind和delegate方法都让监听其它元素的事件。这些事件句柄将在控制器实例销毁后去绑定。

 

你可能感兴趣的:(javascriptmvc)