Google Closure bind / resolve issues with the this keyword
What is the Google Closure's solution for resolving the issues with the this
keyword in JavaScript callbac开发者_运维知识库k functions. It would be so useful in OO style programming.
Is there any conventions or style for OOP in Google Closure???
update How can I access this.darklayer in ViewportSizeMonitor handler???
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.math.Size');
goog.require('goog.style');
goog.require('goog.dom.ViewportSizeMonitor');
goog.provide('ehsun7b.ajax.AjaxBox');
ehsun7b.ajax.AjaxBox = function (url, containerClass) {
try {
this.url = url;
this.containerClass = containerClass;
var viwportSize = goog.dom.getViewportSize();
this.darklayer = goog.dom.createDom("div", {
"style": "width: " + viwportSize.width + "px;" + "height: " +
viwportSize.height + "px;" +
"background-image: url('css/img/50black.png');" +
"z-index: 1000;" +
"position: absolute;" +
"left: 0px; top: 0px;"
});
var vsm = new goog.dom.ViewportSizeMonitor();
goog.events.listen(vsm, goog.events.EventType.RESIZE, function(e) {
console.log("this: " + this.darklayer);
});
this.container = goog.dom.createDom("div", {
"class": this.containerClass
});
goog.dom.appendChild(this.darklayer, this.container);
goog.dom.setTextContent(this.container, "hello ajax box");
this.show = function() {
goog.dom.appendChild(document.body, this.darklayer);
},
this.hide = function() {
goog.dom.removeNode(this.darklayer);
}
} catch (e) {
console.log("error: " + e);
}
};
I changed my class according to the Closure's style this way:
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.math.Size');
goog.require('goog.style');
goog.require('goog.dom.ViewportSizeMonitor');
goog.provide('ehsun7b.ajax.AjaxBox');
ehsun7b.ajax.AjaxBox = function (url, containerClass) {
try {
this.url = url;
this.containerClass = containerClass;
var viwportSize = goog.dom.getViewportSize();
this.darklayer = goog.dom.createDom("div", {
"style": "width: " + viwportSize.width + "px;" + "height: " +
viwportSize.height + "px;" +
"background-image: url('css/img/50black.png');" +
"z-index: 1000;" +
"position: absolute;" +
"left: 0px; top: 0px;"
});
var vsm = new goog.dom.ViewportSizeMonitor();
goog.events.listen(vsm, goog.events.EventType.RESIZE, function(e) {
console.log("this: " + this.darklayer);
});
this.container = goog.dom.createDom("div", {
"class": this.containerClass
});
goog.dom.appendChild(this.darklayer, this.container);
goog.dom.setTextContent(this.container, "hello ajax box");
} catch (e) {
console.log("error: " + e);
}
};
ehsun7b.ajax.AjaxBox.prototype.show = function() {
goog.dom.appendChild(document.body, this.darklayer);
}
ehsun7b.ajax.AjaxBox.prototype.hide = function() {
goog.dom.removeNode(this.darklayer);
}
goog.bind
is the general purpose solution. For example:
goog.bind(this.someFunction, this);
goog.bind(this.someFunction, this, arg1);
goog.bind(this.someFunction, this, arg1, arg2);
The framework is generally designed such that this can be avoided, so it's not common to have to explicitly call goog.bind
.
For example, goog.events.EventHandler
automatically binds callbacks to the handler you set in its constructor.
var handler = new goog.events.EventHandler(this);
handler.listen(something, 'something', this.someFunction); // no need to bind
The array functions also support a handler argument.
goog.array.forEach(elements, this.someFunction, this);
var items = goog.array.map(elements, this.someFunction, this);
And so on. Most parts of the framework make it pretty easy to do this, it's very well designed for "pseudo-classic" inheritance.
For more details, see http://www.bolinfest.com/javascript/inheritance.php
精彩评论