开发者

How to attach an event listener to an object in JS

This seems possible as http://www.knockoutjs.com appears to be doing it. I haven't been able to make enough sense of their code-base to get a similar pattern working though.

Effectively I have a MVVM style application with the UI based on jQuery tabs. Each tab is represented by a view model that I want to be able to validate and fire events based on changes in the model.

I create a representation of my data similar to the following on page load:


$(document).ready(function(){
  thisTab = new ThisTab();
});

function ThisTab(){
  Load: {Load from my model}
  Save: {Save/Persist model to the db (via web service call)}
  Validate: {
    this.Item1 = function(){Validate item 1, do work, refresh fields, whatever.}
  }
}

The model itself is a complex global object and changes to the DOM (inputs, etc.) immediately update the object. Changes to some of those properties should call their associated validate items thisTab.Validate.Item1. I have no issue raising events from the changes. If I bind that event listener to a random DOM element I can call my routines without issue and everything works beautifully. It does seem strange, however, to attach the event to a non-related DOM object.

So the question is: how can I do something like thisTab.addEventListner("someEvent") or $(thisTab).bind("someEvent"), where thisTab is not a DOM element, but instead is a native object. Trying to do it, I always get an error 开发者_如何学Gothat "this method is not supported".


Attaching an event to a standard object does not use the same methods; basically, you would implement your own eventing like so:

function ThisTab()
{
    listeners: [],
    addListener: function(callback) { this.listeners.push(callback); },
    load: { // Finds DOM elements and such, and attaches to their events. The callback from the DOM event should be a method on your object },
    yourDomEventCallback: function() 
    { 
        for(var j = 0; j < this.listeners.length; j++)
            this.listeners[j]();
    }
}

The above code should be used as a starting point, since I just cobbled it together and there are likely syntax errors. Basically, you have taken your object and mapped onto events you want to capture, and then expose methods to attach callback methods that you will call when the hidden DOM events occur. You wont be able to use jQuery's abstractions for DOM events, because such events have no meaning on your custom object.


Bind the event to your regular JS object as you would do for a DOM object.

$(thisTab).bind("someEvent", function() {
    // handler's code here
});

See this example. Using this has one side-effect that jQuery will add a housekeeping identifier as a property on the object - it looks something like jQuery1510587397349299863.

This property named jQuery<timestamp> is added to all DOM objects that have events or data associated with them, and regular objects behave similarly. If you are uncomfortable with your model objects being modified, then use your own callback mechanism which should be fairly easy to add.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜