似乎 kendo 的 unobtrusive-javascript 样式事件调用this
在我的方法上下文中中断。
假设我有一个对象Foo
,实例化为bar = new Foo()
function Foo(){};
Foo.prototype.name = "Herring";
Foo.prototype.doSomething = function(e) {
alert(this.name);
};
bar = new Foo();
并使用 data-click 例如附加事件
<a data-role="button" data-click="bar.doSomething">Click Me</a>
对象上下文bar
被替换(不知道为什么,因为我们有方便的element
容器。)所以this.name
是未定义的。
我已经var self = this;
在对象构造函数中尝试过旧的,但它不起作用,有谁知道解决这个问题的最佳方法是什么?
更新:哈克解决方法
因为我真的不想失去将模块包装为类的好处,所以我创建了事件调用函数包装器,然后调用适当对象上的方法。
例如,将标记连接到包装函数。
<a data-role="button" data-click="doSomething">Click Me</a>
包装函数只调用object.method。
function doSomething(e){ bar.doSomething(e) };
现在,这达到了预期的结果,但它非常可怕,从标记调用的每个事件都必须具有像上面那样的代理函数。所以想象一下你有 300 个事件的场景......你会立即明白为什么这很可怕。
如果没有其他解决方案,我非常希望有。我将发布此解决方法作为答案,但就我而言,它远非理想。
脚注
老实说,这似乎是剑道的主要架构缺陷,因为这种从标记中调用事件的方法是“剑道方式”。显然它不能被修补,因为可能已经有相当多的代码this
作为对 html 元素的引用来处理。
能够覆盖它,或者能够通过可以传递调用的通用处理程序来路由这些事件调用,本质上是通用代理函数,是可以处理这种情况的可能方式。它也可以是kendo.
对象上的简单可配置值。
理论解决方案
如果可行,我将发布后续操作,理论上可以在通用代理上引发事件,并让它调用适当范围的函数。
假设我们使用事件属性来调用代理,然后创建一个单独的属性来传达对象/方法调用。例如。
<a data-role="button" data-click="prox" data-prox="o.eventHandler">Click Me</a>
代理函数将从prox
属性数据集中提取:
方法 - 使用 eval
不是因为我是邪恶的,而是必须的。
// sitting in global namespace
function prox(e){
var p = e.sender.element.data['prox'];
// make sure our delegate is a function.
if("function" == eval("typeof "+p)) {
eval(p + "(e)");
}
}
显然我想要一个更好的方法来做到这一点,但至少它是干燥的。
(我一会儿会做一个非评估方法......)
开始评估...
让我们使用窗口上下文来定位对象/方法。
function prox(e) {
var p = e.sender.element.data['prox'];
if(p.indexOf(".") == -1){
// global function : where *this* is window.
// check you've got the function if not ditch it.
if("function" == typeof window[p]) window[p](e);
} else {
// object/method (one level deep only.)
var s = p.split(".");
var o = s[0], m = s[1];
// check the object/method is a function before executing it.
if("function" == typeof window[o][p]) window[o][p](e);
}
}
当然对于全局(窗口)范围的函数, this 作为元素可能更有用,但在这种情况下,你可以选择,我会省略