2014-01-27 59 views
1

我想实现一个小MVC框架,现在我正在实现视图模型绑定器,我的意思是,当模型更改时,触发刷新/渲染/模型上的任何操作。所以,我需要一个对象的事件监听器:关于非DOM元素的事件监听器

model.on("customEvent",appendItem); 

$("#button").on("click",function(){ 
    model.add(item); 
    model.trigger("customEvent"); 
}); 

function appendItem(item) { 
    $("#content").append(item.toHTML()); 
} 

那么我怎样才能创建我的事件侦听器的对象?

+0

尝试使用knockout.js:http://www.knockoutjs.com –

+0

pub/sub pattern – Paulpro

回答

4

如果您已经在使用jQuery,则可以使用其内置的事件处理工具。

这是一个鲜为人知的事实,您可以将任何类型的Javascript对象放入jQuery集合中,而不仅仅是DOM元素。然后,您可以在这些对象上使用有限的一组jQuery方法(.data().prop(),.on(),.off(),.trigger().triggerHandler())。

//create the model - it can be any kind of object 
var model = {}; 

//pass it to the jQuery function and you have a jQuery collection 
//you can put an event handler on the object 
$(model).on('customEvent', function() { console.log('hehe'); }); 

//and trigger it 
$(model).trigger('customEvent'); 
+0

问题在于我的模型是以这种方式构建的'var Model = function(){}'所以不是构建的对象var = {} – grivcon

+0

@ user2657856它是如何构建的并不重要。我很肯定它是一个对象;)。 – kapa

0

对于谁是不使用jQuery和有兴趣的接线自己塞入那些,这里是你如何可以实现类似的目的:

/** 
 
* EventfulObject constructor/base. 
 
* @type EventfulObject_L7.EventfulObjectConstructor|Function 
 
*/ 
 
var EventfulObject = function() { 
 
    /** 
 
    * Map from event name to a list of subscribers. 
 
    * @type Object 
 
    */ 
 
    var event = {}; 
 
    /** 
 
    * List of all instances of the EventfulObject type. 
 
    * @type Array 
 
    */ 
 
    var instances = []; 
 
    /** 
 
    * @returns {EventfulObject_L1.EventfulObjectConstructor} An `EventfulObject`. 
 
    */ 
 
    var EventfulObjectConstructor = function() { 
 
    instances.push(this); 
 
    }; 
 
    EventfulObjectConstructor.prototype = { 
 
    /** 
 
    * Broadcasts an event of the given name. 
 
    * All instances that wish to receive a broadcast must implement the `receiveBroadcast` method, the event that is being broadcast will be passed to the implementation. 
 
    * @param {String} name Event name. 
 
    * @returns {undefined} 
 
    */ 
 
    broadcast: function(name) { 
 
     instances.forEach(function(instance) { 
 
     (instance.hasOwnProperty("receiveBroadcast") && typeof instance["receiveBroadcast"] === "function") && 
 
     instance["receiveBroadcast"](name); 
 
     }); 
 
    }, 
 
    /** 
 
    * Emits an event of the given name only to instances that are subscribed to it. 
 
    * @param {String} name Event name. 
 
    * @returns {undefined} 
 
    */ 
 
    emit: function(name) { 
 
     event.hasOwnProperty(name) && event[name].forEach(function(subscription) { 
 
     subscription.process.call(subscription.context); 
 
     }); 
 
    }, 
 
    /** 
 
    * Registers the given action as a listener to the named event. 
 
    * This method will first create an event identified by the given name if one does not exist already. 
 
    * @param {String} name Event name. 
 
    * @param {Function} action Listener. 
 
    * @returns {Function} A deregistration function for this listener. 
 
    */ 
 
    on: function(name, action) { 
 
     event.hasOwnProperty(name) || (event[name] = []); 
 
     event[name].push({ 
 
     context: this, 
 
     process: action 
 
     }); 
 

 
     var subscriptionIndex = event[name].length - 1; 
 

 
     return function() { 
 
     event[name].splice(subscriptionIndex, 1); 
 
     }; 
 
    } 
 
    }; 
 

 
    return EventfulObjectConstructor; 
 
}(); 
 

 
var Model = function(id) { 
 
    EventfulObject.call(this); 
 
    this.id = id; 
 
    this.receiveBroadcast = function(name) { 
 
    console.log("I smell another " + name + "; and I'm model " + this.id); 
 
    }; 
 
}; 
 
Model.prototype = Object.create(EventfulObject.prototype); 
 
Model.prototype.constructor = Model; 
 

 
// ---------- TEST AND USAGE (hopefully it's clear enough...) 
 
// ---------- note: I'm not testing event deregistration. 
 

 
var ob1 = new EventfulObject(); 
 
ob1.on("crap", function() { 
 
    console.log("Speaking about craps on a broadcast? - Count me out!"); 
 
}); 
 

 
var model1 = new Model(1); 
 

 
var model2 = new Model(2); 
 
model2.on("bust", function() { 
 
    console.log("I'm model2 and I'm busting!"); 
 
}); 
 

 
var ob2 = new EventfulObject(); 
 
ob2.on("bust", function() { 
 
    console.log("I'm ob2 - busted!!!"); 
 
}); 
 
ob2.receiveBroadcast = function() { 
 
    console.log("If it zips, I'll catch it. - That's me ob2."); 
 
}; 
 

 
console.log("start:BROADCAST\n---------------"); 
 
model1.broadcast("crap"); 
 
console.log("end :BROADCAST\n---------------\n-\n-\n"); 
 
console.log("start:EMIT\n---------------"); 
 
ob1.emit("bust"); 
 
console.log("end:EMIT\n---------------");
<h1>THE CODE IS IN THE JavaScript SECTION!</h1> 
 
<h3>AND... THE SHOW IS ON YOUR CONSOLE!</h3>