0

I've implemented the observer pattern in JS in a very universal way. Now I realized that there is a conceptional problem and I don't know how to solve it. Could you give me a tipp how to solve it? (particularly in a very smart way :-) ) This is the code:

var Oberserverable = function() {
    var subscribers = { /* some delegated functions in here */ };        
    return {
        attach: function (obj, fn) { subscribers[obj] = { src: obj, fn: fn }; },
        detach: function (obj) { delete subscribers[obj]; },    
        notify: function (args) { 
            for(var o in subscribers) { 
                if(typeof args === "object") { args.target = subscribers[o].src; }
                /* TODO return */ subscribers[o].fn.call(window, args); 
            } 
        },
        count: function () { var size = 0; for(var o in subscribers) { size++; } return size; } 
    };
};

I'd like that each delegated function returns its value. But this would end the loop what I'd like to prevant.

Example case where I'm using it; workaround for crappy IE8 Eventhandeling:

window.addEvent = function (obj, type, fn, bub) {
    if(obj.addEventListener) {
        return obj.addEventListener(type, fn, bub ? bub : false);
    }

    if(obj.attachEvent && type == "DOMContentLoaded") type = "load";

    // no use of attachEvent() 'cause of very buggy behaviour in IE<=8
    // http://stackoverflow.com/questions/15952943/ie-attachevent-call-returns-true-but-handler-shows-null        
    if(!obj["e"+type]) obj["e"+type] = new Oberserverable();
    obj["e"+type].attach("e"+obj+fn, fn);
    if(!obj["on"+type]) { 
        obj["on"+type] = function(e) {
            e = e || window.event;  
            e.cancelBubble = bub;
            return obj["e"+type].notify(e) || (type != "contextmenu"); // suppressing context menu in IE8 as default
        };
    }
}
ortwic
  • 73
  • 2
  • 8
  • 1
    function returns only one value. You can aggregate all results in array and return it, or you can pass callback function an call it with each result in loop – Ivan Solntsev Sep 09 '13 at 08:20
  • I think the problem are the differing concepts. I'm calling many functions where each got their own return value. But there were assigned to obj["on"+type] only, a wrapper function. So how to decide which return value counts? That might be the reasen why addEventListener() returns no value by specification. – ortwic Sep 09 '13 at 08:49

1 Answers1

0

EUREKA!

I think I've got the solution. The actual problem is not the Oberserverable pattern but the example case itself. Maybe I should do sth. like this:

        obj["on"+type] = function(e) {
            e = e || window.event;  
            e.cancelBubble = bub;
            obj["e"+type].notify(e); 
            if(typeof e.preventDefault == "function") {
                return e.preventDefault();
            }
        };

And the other part simular to this:

addEvent(document, "contextmenu", function(e) {
    document.defaultAction = false;
    if (e.preventDefault)
        e.preventDefault();
    else
        e.preventDefault = function() { return false; };

    if (e.stopPropagation)
        e.stopPropagation();

    if (e.returnValue)
        e.returnValue = false;
});

It seems to work this way but I'm not sure about compliance and side effects.

ortwic
  • 73
  • 2
  • 8