Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript KendoUI数据-属性事件处理程序和';这';范围_Javascript_This_Kendo Ui_Unobtrusive Javascript - Fatal编程技术网

Javascript KendoUI数据-属性事件处理程序和';这';范围

Javascript KendoUI数据-属性事件处理程序和';这';范围,javascript,this,kendo-ui,unobtrusive-javascript,Javascript,This,Kendo Ui,Unobtrusive Javascript,在我的方法上下文中,kendo的低调javascript风格事件调用似乎打破了这一点 假设我有一个对象Foo,实例化为bar=newfoo() 并使用数据连接事件,例如单击 <a data-role="button" data-click="bar.doSomething">Click Me</a> 包装器函数只调用object.method function doSomething(e){ bar.doSomething(e) };   现在,这实现了预期的结果,但

在我的方法上下文中,kendo的低调javascript风格事件调用似乎打破了这一点

假设我有一个对象
Foo
,实例化为
bar=newfoo()

并使用数据连接事件,例如单击

<a data-role="button" data-click="bar.doSomething">Click Me</a>
包装器函数只调用object.method

function doSomething(e){ bar.doSomething(e) };  
现在,这实现了预期的结果,但它非常可怕,从标记调用的每个事件都必须有一个类似于上面的代理函数。想象一个场景,你有300个事件。。。你马上就会明白为什么这很可怕

如果没有其他解决办法,我非常希望有。我将发布这个解决方案作为一个答案,但就我而言,这远远不是理想的

脚注 老实说,这似乎是剑道中的主要架构缺陷,因为这种从标记调用事件的方法是“剑道方式”。显然,它无法修补,因为可能已经有相当多的代码将此作为html元素的引用来处理

能够覆盖它,或者能够通过一个可以传递调用的通用处理程序(本质上是一个通用代理函数)路由这些事件调用,都是可能的处理方法。它也可以是
kendo.
对象上的简单可配置值

理论解 如果这有效,我将发布后续文章。理论上,可以在通用代理上抛出事件,并让它调用适当范围的函数

假设我们使用事件属性调用代理,然后创建一个单独的属性来传递对象/方法调用。比如说

<a data-role="button" data-click="prox" data-prox="o.eventHandler">Click Me</a>
显然,我希望有更好的方法来做这件事,但至少是干的

(我马上会做一个非评估方法…)

开始评估。。。 让我们使用窗口上下文来定位对象/方法

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);
   }
}
当然,对于全局(窗口)范围的函数,作为元素,这可能更有用,但在这种情况下,您可以选择,我将省略使用中的

版本。 警告 如果在同一个元素上有多个处理程序,
prox()
是不合适的,例如,如果您有
data init
data show
等。
prox
无法区分,将失败


我可能会更新它,特别是如果这成为我的一个普遍使用案例。

我暂时尝试了第三种方法,使用了非通用技术,其工作原理如下

伪代码: 不像prox方法那样灵活,但适合我的用例,并且至少不需要与我们想要使用的方法分离的单独函数代理。我们可以通过预先进行类型检查和重新调用,使其更加简洁

e、 g

这也意味着我的标记中不需要自定义
数据-
属性

注意:对于将有多个实例的对象,此方法是有问题的,但是,我应用的对象是单个实例

如果您有需要特定于实例的处理程序(这是我提出这个问题的主要原因),
prox
方法比这更合适,这只是一种更简洁的方法,可以使用jQuery proxy()

或供内部使用

$("btn").click($.proxy(this.doSomething), this);

我使用JS proxy Polyfill开发了一个代理方法,该方法通过custon html data-*属性中的参数简化了对自定义逻辑的调用

包括

例如,上传组件

<input type=file ... 
       data-success="eventproxy.customsuccesshandler"
       data-proxy-customsuccesshandler='{widget:"kendoGrid",method:"<myJqueryDataDefinedMethod>",id:"<gridId>"}'
       ....
/>
在定义自定义属性之后

data-proxy-CUSTOMKEY
数据代理CUSTOMKEY包含可用于实现自定义逻辑的参数(JSON编码)

我建议使用自定义逻辑,它可以通过$.data检索存储在kendo小部件网格上的JS方法

$("#" + proxyParams.id).data(proxyParams.widget).element.data(proxyParams.method)
例如,您可以使用以下命令将方法绑定到网格

$('#my-grid-id').data("kendoGrid").element.data('methodName',function(e){ 
    // my implementation 
});

问题是如何使用剑道的数据属性来实现这一点。
MyObject = {
   method : function(e) {
      if (! this instanceof MyObject) myInstance.method(e); // re-call

      // Method body... 

   }
}
myInstance = new MyObject();
function Foo(){};

Foo.prototype.name = "Herring";
Foo.prototype.doSomething = function(e) {
   alert(this.name);
};

bar = new Foo();

$("btn").click($.proxy(bar.doSomething), bar);
$("btn").click($.proxy(this.doSomething), this);
function makeGridTemplateEventProxy(o) {
    return new Proxy(o, {
        get(target, eventName) {
            return function (options) {
                return templateEventProxy(options, eventName);
            }
        }
    });
}

templateEventProxy: function (options, attribute) {
    if (!options.sender.element.attr('data-proxy-' + attribute)) {
        throw new Error('Cannot find attribute data-proxy-' + attribute + ' on ' + options.sender.name + ' widget');
    }
    var proxyParams = JSON.parse(options.sender.element.attr('data-proxy-' + attribute));

    method = $("#" + proxyParams.id).data(proxyParams.widget).element.data(proxyParams.method);

    if (method && typeof method == 'function') {
        return $.proxy(method, this)(options);
    }

    return null;

}


var eventproxy = makeGridTemplateEventProxy({});
<input type=file ... 
       data-success="eventproxy.customsuccesshandler"
       data-proxy-customsuccesshandler='{widget:"kendoGrid",method:"<myJqueryDataDefinedMethod>",id:"<gridId>"}'
       ....
/>
data-success="eventproxy.CUSTOMKEY"
data-proxy-CUSTOMKEY
$("#" + proxyParams.id).data(proxyParams.widget).element.data(proxyParams.method)
$('#my-grid-id').data("kendoGrid").element.data('methodName',function(e){ 
    // my implementation 
});