Javascript 从jQuery自定义触发器/绑定事件返回数据
我正在使用jQuery触发元素上的自定义事件,我希望事件处理程序能够将数据(以对象的形式)传递回调用它的方法。触发器和处理程序位于不同的作用域和文件中,不能以常规方式合并或共享。(触发器方法是我正在编写的实用程序库的一部分,事件处理程序是我的前端视图模板的一部分) 我知道这段代码不起作用,但我写这段代码是为了说明我希望尝试的内容。该模式基于我在.NET中所做的工作Javascript 从jQuery自定义触发器/绑定事件返回数据,javascript,jquery,events,javascript-events,Javascript,Jquery,Events,Javascript Events,我正在使用jQuery触发元素上的自定义事件,我希望事件处理程序能够将数据(以对象的形式)传递回调用它的方法。触发器和处理程序位于不同的作用域和文件中,不能以常规方式合并或共享。(触发器方法是我正在编写的实用程序库的一部分,事件处理程序是我的前端视图模板的一部分) 我知道这段代码不起作用,但我写这段代码是为了说明我希望尝试的内容。该模式基于我在.NET中所做的工作 var data = { foo: 'bar' } element.trigger('some-event', data) if(d
var data = { foo: 'bar' }
element.trigger('some-event', data)
if(data.foo != 'bar')
alert('someone changed foo!')
而处理者
element.bind('some-event', function(event, data)
{
if(some_condition)
data.foo = 'biz'
});
element.bind('loading-data', function(event, data)
{
if(data.is_password == true)
{
data.foo = '*******' //changed property persisted to triggering method and processed normally
}
if(data.type == 'abc')
{
element.append('<input value="' + data.foo + '"/>');
data.abort_render = true; //signals to the triggering method that it should not render the data to the page
}
}
具体的实现对我来说并不重要,只要我没有重新安排代码,使触发器和绑定都在同一范围内
如何从事件处理程序获取返回值
编辑
为了提供更多的上下文,触发方法负责获取和处理数据,并最终将其作为标记呈现给页面。在此之前,它会使用相同的已处理的数据
对象引发自定义事件,以便应用程序的其他组件有机会对已处理的数据进行处理
在某些情况下,事件处理程序修改该数据集或事件信号到触发方法将是有益的,因为该数据已被处理,不需要额外的处理或呈现
像下面这样。在本例中,处理程序可能会根据某些属性值更改数据的显示方式。它还可以选择以不同的方式呈现数据(例如,输入
),而不是触发功能中的默认呈现(例如,标签
)
这个实现就是一个例子,但是从处理程序返回一个对象,或者修改处理程序中的数据以使触发方法能够访问它的最终目标对于我的实际项目来说是常见的
var data = load_data();
element.trigger('loading_data', data);
if(data.abort_render!==true)
{
element.append('<label>Foo</label>')
element.append('<span>' + data.foo + '</span>')
}
var data=load_data();
元素。触发器(“加载数据”,数据);
if(data.abort_render!==true)
{
元素。追加('Foo')
元素。追加(“”+data.foo+“”)
}
而处理者
element.bind('some-event', function(event, data)
{
if(some_condition)
data.foo = 'biz'
});
element.bind('loading-data', function(event, data)
{
if(data.is_password == true)
{
data.foo = '*******' //changed property persisted to triggering method and processed normally
}
if(data.type == 'abc')
{
element.append('<input value="' + data.foo + '"/>');
data.abort_render = true; //signals to the triggering method that it should not render the data to the page
}
}
element.bind('load-data',函数(事件,数据)
{
if(data.is_password==true)
{
data.foo='******'//已更改的属性保留到触发方法并正常处理
}
如果(data.type==“abc”)
{
元素。追加(“”);
data.abort_render=true;//向触发方法发出不应将数据呈现给页面的信号
}
}
有一种方法。下面是jQuery方法(由本答案中的示例2修改而来:)
要获得更强健的解决方案,请尝试以下方法:
// Bind the event to the element
jQuery('body').on(element, 'some-event', function(event, data) {
// Call the callback function, pass in the data
eventCallback(data);
});
// Call this function to set up the data and trigger the event
function triggerMyEvent() {
var data = { foo: 'bar' };
element.trigger('some-event', data);
}
// The callback function set in the event binding above
function eventCallback(data) {
if(data.foo != 'bar')
alert('someone changed foo!');
}
挑战可能在逻辑/代码流中。下面是代码(来自您的问题)-我添加了一些注释,试图帮助解释流程:
// Command 1: This will run first
var data = load_data();
// Command 2: This will run second
element.trigger('loading_data', data);
// Command 3: This will run independently of the trigger callback
// and the data will not be modified based on the trigger.
// You will want to restructure your code to run this within the
// trigger callback
if(data.abort_render!==true)
{
element.append('<label>Foo</label>')
element.append('<span>' + data.foo + '</span>')
}
// Event handler (will run independently of Command 3)
jQuery('body').on(element, 'loading_data', function(event, data) {
// THIS will run independently of the "Command 3" code above
// and may or may not be done before Command 3 is run.
// That's why this needs to trigger the code that handles
// the data checks and various outputs based on the data
handleLoadData(data);
}
// A specific function designed to be run AFTER event handler,
// specifically to handle the various data settings that may be set.
function handleLoadData(data) {
if(data.is_password == true) {
data.foo = '*******' //changed property persisted to triggering method and processed normally
}
if(data.type == 'abc') {
element.append('<input value="' + data.foo + '"/>');
data.abort_render = true; //signals to the triggering method that it should not render the data to the page
}
// This code will need to be moved here, because data may
// not be updated when Command 3 is run above. Alternatively,
// You could put it in another function, and call that function
// from here.
if(data.abort_render!==true) {
element.append('<label>Foo</label>')
element.append('<span>' + data.foo + '</span>')
}
}
//命令1:这将首先运行
var数据=加载_数据();
//命令2:第二次运行
元素。触发器(“加载数据”,数据);
//命令3:这将独立于触发器回调运行
//并且不会根据触发器修改数据。
//您需要重新构造代码,以便在
//触发回调
if(data.abort_render!==true)
{
元素。追加('Foo')
元素。追加(“”+data.foo+“”)
}
//事件处理程序(将独立于命令3运行)
jQuery('body')。关于(元素,'loading_data',函数(事件,数据){
//这将独立于上面的“命令3”代码运行
//在运行命令3之前,可以执行,也可以不执行。
//这就是为什么需要触发处理
//数据检查和基于数据的各种输出
handleLoadData(数据);
}
//设计为在事件处理程序之后运行的特定函数,
//专门用于处理可能设置的各种数据设置。
函数handleLoadData(数据){
if(data.is_password==true){
data.foo='******'//已更改的属性保留到触发方法并正常处理
}
如果(data.type==“abc”){
元素。追加(“”);
data.abort_render=true;//向触发方法发出不应将数据呈现给页面的信号
}
//此代码需要移到此处,因为数据可能会丢失
//当在上面运行命令3时不会更新。或者,
//你可以把它放在另一个函数中,然后调用这个函数
//从这里开始。
if(data.abort_render!==true){
元素。追加('Foo')
元素。追加(“”+data.foo+“”)
}
}
将不会按您期望的顺序运行。请参阅上面的注释以帮助jQuery中的,这似乎很难完成。请参阅以下回答:我知道如何将数据从触发器
传递给处理程序。我需要将数据从处理程序传递回引发事件的方法。我不相信您引用的问题是查看答案的部分:乘客.on('brake.car',函数(evt,car,brakeAmount){…
类似于您的容器.on(元素,函数(事件,数据){…
Jeff-我修改了我的答案,以纳入您的详细信息。我想我一定是遗漏了什么。我看不到其他问题中事件处理程序返回数据的任何地方。您在这里提供的示例也没有从事件处理程序返回任何内容到调用范围。您已将警报
粘贴在eve中nt处理程序,这是对我的问题的一个根本性改变。你是否建议我在DOM树的更上层添加第二个事件处理程序,以便再次捕获事件?这可能会起作用…@Jeff-是的,你必须这样做。你的问题中的代码位置我错认为是“示例代码”,但必须真正位于
上的回调中,否则必须由
上的调用