Javascript custom "event" listener, using prototype implementation OOP
I have been trying to wrap my head around this one, and a lot of tutorials and sites have been suggesting the creation of a separate event object, which seems to be a bit of overkill for just implementing one function to happen at some point in the object.
Basically I want to have a custom "onComplete" event to fire when certain methods are called within the object being used. I have an GMaps control object that is toggled on or off. When on it allows manipulation of polylines on the map, but when turned off it disables the manipulation, at which point I would like the polyline data to be stored. What I am attempting to do is allow users of the object to create their own event to listen for the turned off event, and allow them to access the polyline data from that object. How can I do that?
This is my code thus far:
function ToggleLineDrawControl() {}
ToggleLineDrawControl.prototype = new GControl();
ToggleLineDrawControl.prototype._on = false;
ToggleLineDrawControl.prototype._button = false;
ToggleLineDrawControl.prototype._map = false;
ToggleLineDrawControl.prototype._overlay = false;
ToggleLineDrawControl.prototype._plots = [];
ToggleLineDrawControl.prototype._line = false;
ToggleLineDrawControl.prototype._addPlotListener = false;
ToggleLineDrawControl.prototype._onComplete = false;
ToggleLineDrawControl.prototype.initialize = function(map) {
this._map = map;
var me = this;
var container = document.createElement('div');
var buttonDiv = document.createElement('div');
this._button = buttonDiv;
this.setButtonStyle_();
container.appendChild(this._button);
this._button.appendChild(document.createTextNode('Plot'));
GEvent.addDomListener(this._button, 'click', function() {
if(!this._on) {
this.style.backgroundColor = '#333333';
this.style.color = 'white';
this.firstChild.nodeValue = 'Done';
me.startPlotting();
this._on = true;
} else {
this.style.backgroundColor = 'white';
this.style.color = '#333333';
this.firstChild.nodeValue = 'Plot'
me.stopPlotting();
this._on = false;
}
});
this._map.getContainer().appendChild(container);
return container;
};
ToggleLineDrawControl.prototype.getDefaultPosition = function() {
return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7, 57));
};
ToggleLineDrawControl.prototype.setButtonStyle_ = function() {
this._button.style.textDecoration = 'none';
this._button.style.color = '#333333';
this._button.style.backgroundColor = 'white';
this._button.style.font = 'small Arial';
this._button.style.border = '1px solid black';
this._button.style.padding = '2px';
this._button.style.marginBottom = '3px';
this._button.style.textAlign = 'center';
this._button.style.width = '5em';
this._button.style.cursor = 'pointer';
};
ToggleLineDrawControl.prototype.setPlot = function(latlng) {
var wicon = new GIcon();
wicon.image = 'http://www.site.com/images/waypoint2.png';
wicon.iconSize = new GSize(32, 32);
wicon.iconAnchor = new GPoint(8, 28);
var marker = new GMarker(latlng, {icon: wicon});
this._map.addOverlay(marker);
this._plots.push(latlng);
this.drawLines();
};
ToggleLineDrawControl.prototype.drawLines = function() {
var numPlots = this._plots.length;
if(this._line != false) {
this._map.removeOverlay(this._line);
}
if(numPlots > 1) {
this._line = new GPolyline(this._plots, '#cc0000', 2, 0.75);
this._map.addOverlay(this.开发者_StackOverflow中文版_line);
}
}
ToggleLineDrawControl.prototype.startPlotting = function() {
var me = this;
this._addPlotListener = GEvent.addListener(this._map, 'click', function(o, l, ol) {
me.setPlot(l);
});
};
ToggleLineDrawControl.prototype.stopPlotting = function() {
GEvent.removeListener(this._addPlotListener);
};
ToggleLineDrawControl.prototype.onComplete = function(callback) {
this._onComplete = callback // get this to somehow be listener event method
};
You may want to move your onComplete function near the top as that is what you seem to be asking about.
But, I don't understand the flow.
If I use your library, and I want to pass in a function, as the event handler, for onComplete, you store it in a prototype variable (this._onComplete
), so each object only has one callback function.
Where is this ever being called?
Once you finish you should be calling the callback, passing in the object as a parameter:
if (this._onComplete != false this._onComplete(this);
Ok solved it with a bit of help from a former colleague. Sometimes you just need to step out of your own head, and ask the right person. Anyhow, James was right in that I was not even calling the method in the first place. So, a colleague of mine suggested creating a reference to the custom function in the main object function as an option:
function ToggleLineDrawControl(options) {
this._onComplete = options.onComplete;
}
... and in the stopPlotting() method, where I want this method to get called:
ToggleLineDrawControl.prototype.stopPlotting = function() {
...
this._onComplete(this);
};
Works like a charm
精彩评论