为什么不能使用 lambda 构造将方法订阅到数据表的点击事件?
Why cannot subsribe a method to a datatable's click event with the lambda construct?
我在 angular 5 中使用数据表 (datatables.net),我正在订阅一种方法来响应 tr
上的点击事件,如下所示:
const tableRef = this.table; // bound datatable and router to scope
const routerRef = this.router; // so I can use them inside the callBack
this.table.on('click', 'tbody tr', function (e) {
const $tr = $(this).closest('tr');
const data = tableRef.row($tr).data();
if (data !== undefined) {
routerRef.navigateByUrl(`/some/url/details/${data.id}`);
}
});
它几乎与 datatables.net 上的样本相同
网站。事情是这样的,后来我决定像下面这样更改我的代码:
this.table.on('click', 'tbody tr', this.rowClicked(this.table, this.router));
//...
private rowClicked(table, router: Router) {
return (e) => {
const $tr = $(this).closest('tr');
const data = table.row($tr).data();
if (data !== undefined) {
router.navigateByUrl('/some/url/details/`${data.id}`');
}
}
}
而且...令我惊讶的是它什么也没做,连眨眼都没有!然后我继续
并将 console.log('row clicked');
放入 lambda 中(如果可以这样命名,
我真的是 typescript 的新手),每当我点击 tr
但 data
时它就会打印出来
总是 undefined
。我什至为 $("#my-datatable-id").DataTable()
更改了 table
变量
仍然没有运气。几分钟后,我决定 git diff
文件并意识到唯一的
不同之处在于回调的构造方式(使用关键字 function
)所以我这样做并将 lambda 更改为:
private rowClicked(table, router: Router) {
return function (e) {
// same as before
}
}
猜猜看,成功了!它像魅力一样获取了 tr
的数据。那么,任何人都可以
向我解释为什么在使用 lambda 时我无法从行中获取 data
和
当我使用 function
构造时。提前致谢!
我不知道 Angular,但我认为 this.table.on
正在将自定义 this
上下文传递给 $(this)
所必需的回调你打算。当您使用箭头函数时,this.table.on
传递的上下文将被忽略,而 this
会引用调用 rowClicked
的对象,因此您会得到不同的结果。
如果我没记错的话,是因为Javascript Closures在this
左右。
这两个不产生相同的this
:
this.table.on('click', 'tbody tr', function (e) {
// "this" is what you think it is
});
对
this.table.on('click', 'tbody tr', this.rowClicked(this.table, this.router));
private rowClicked(table, router: Router) {
// "this" should be window
return (e) => {
const $tr = $(this).closest('tr');
const data = table.row($tr).data();
if (data !== undefined) {
router.navigateByUrl('/some/url/details/`${data.id}`');
}
}
}
您应该可以简单地修复它:
this.table.on('click', 'tbody tr', () => this.rowClicked(this.table, this.router));
或
this.table.on('click', 'tbody tr', () => { return this.rowClicked(this.table, this.router); });
因为上面创建了...好吧,我会调用,这个上的一个匿名函数然后内部调用rowClicked
的范围是正确的(不是window).
我在 angular 5 中使用数据表 (datatables.net),我正在订阅一种方法来响应 tr
上的点击事件,如下所示:
const tableRef = this.table; // bound datatable and router to scope
const routerRef = this.router; // so I can use them inside the callBack
this.table.on('click', 'tbody tr', function (e) {
const $tr = $(this).closest('tr');
const data = tableRef.row($tr).data();
if (data !== undefined) {
routerRef.navigateByUrl(`/some/url/details/${data.id}`);
}
});
它几乎与 datatables.net 上的样本相同 网站。事情是这样的,后来我决定像下面这样更改我的代码:
this.table.on('click', 'tbody tr', this.rowClicked(this.table, this.router));
//...
private rowClicked(table, router: Router) {
return (e) => {
const $tr = $(this).closest('tr');
const data = table.row($tr).data();
if (data !== undefined) {
router.navigateByUrl('/some/url/details/`${data.id}`');
}
}
}
而且...令我惊讶的是它什么也没做,连眨眼都没有!然后我继续
并将 console.log('row clicked');
放入 lambda 中(如果可以这样命名,
我真的是 typescript 的新手),每当我点击 tr
但 data
时它就会打印出来
总是 undefined
。我什至为 $("#my-datatable-id").DataTable()
更改了 table
变量
仍然没有运气。几分钟后,我决定 git diff
文件并意识到唯一的
不同之处在于回调的构造方式(使用关键字 function
)所以我这样做并将 lambda 更改为:
private rowClicked(table, router: Router) {
return function (e) {
// same as before
}
}
猜猜看,成功了!它像魅力一样获取了 tr
的数据。那么,任何人都可以
向我解释为什么在使用 lambda 时我无法从行中获取 data
和
当我使用 function
构造时。提前致谢!
我不知道 Angular,但我认为 this.table.on
正在将自定义 this
上下文传递给 $(this)
所必需的回调你打算。当您使用箭头函数时,this.table.on
传递的上下文将被忽略,而 this
会引用调用 rowClicked
的对象,因此您会得到不同的结果。
如果我没记错的话,是因为Javascript Closures在this
左右。
这两个不产生相同的this
:
this.table.on('click', 'tbody tr', function (e) {
// "this" is what you think it is
});
对
this.table.on('click', 'tbody tr', this.rowClicked(this.table, this.router));
private rowClicked(table, router: Router) {
// "this" should be window
return (e) => {
const $tr = $(this).closest('tr');
const data = table.row($tr).data();
if (data !== undefined) {
router.navigateByUrl('/some/url/details/`${data.id}`');
}
}
}
您应该可以简单地修复它:
this.table.on('click', 'tbody tr', () => this.rowClicked(this.table, this.router));
或
this.table.on('click', 'tbody tr', () => { return this.rowClicked(this.table, this.router); });
因为上面创建了...好吧,我会调用,这个上的一个匿名函数然后内部调用rowClicked
的范围是正确的(不是window).