为什么不能使用lambda构造将方法替换为数据表的click事件?

时间:2018-09-18 01:40:40

标签: typescript datatables angular5

我正在使用角度5中的数据表(datatables.net),并且正在订购一种方法来响应/// Represents one property declaration in an Objective-C interface. /// /// For example: /// \code{.mm} /// \@property (assign, readwrite) int MyProperty; /// \endcode class ObjCPropertyDecl : public NamedDecl { public: enum PropertyAttributeKind { OBJC_PR_noattr = 0x00, OBJC_PR_readonly = 0x01, OBJC_PR_getter = 0x02, OBJC_PR_assign = 0x04, OBJC_PR_readwrite = 0x08, OBJC_PR_retain = 0x10, OBJC_PR_copy = 0x20, OBJC_PR_nonatomic = 0x40, OBJC_PR_setter = 0x80, OBJC_PR_atomic = 0x100, OBJC_PR_weak = 0x200, OBJC_PR_strong = 0x400, OBJC_PR_unsafe_unretained = 0x800, /// Indicates that the nullability of the type was spelled with a /// property attribute rather than a type qualifier. OBJC_PR_nullability = 0x1000, OBJC_PR_null_resettable = 0x2000, OBJC_PR_class = 0x4000 // Adding a property should change NumPropertyAttrsBits }; enum { /// Number of bits fitting all the property attributes. NumPropertyAttrsBits = 15 }; /* Omitted */ }; 上的点击事件,如下所示:

tr

它几乎与datatables.net上的示例相同 网站。问题是,后来我决定像下面的代码一样更改代码:

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}`);
    }
});

而且...令我惊讶的是,它什么也没做,甚至没有眨眼!然后我继续 并将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}`'); } } } 放在lambda中(如果可以这样命名的话, 我真的不是打字稿新手),只要我点击console.log('row clicked');tr时,它就会打印出来 一直是data。我什至更改了undefined的{​​{1}}变量 仍然没有运气。几分钟后,我决定table文件,并意识到唯一 区别在于callBack的构造方式(使用关键字$("#my-datatable-id").DataTable()),所以我这样做了,并将lambda更改为:

git diff

猜猜是什么,它起作用了!它像超级按钮一样获取function的数据。所以,任何一个 向我解释为什么使用lambda时我无法从行中获取private rowClicked(table, router: Router) { return function (e) { // same as before } } 并 当我使用tr构造时。预先感谢!

2 个答案:

答案 0 :(得分:2)

我不了解Angular,但我假设this.table.on会将自定义this上下文传递给回调,这对于$(this)正常工作是必需的。当您使用箭头功能时,this.table.on传递的上下文将被忽略,而this指向调用了rowClicked的对象,因此您会得到不同的结果。

答案 1 :(得分:0)

如果我没记错的话,是因为this周围有Javascript Closures

这两个不会产生相同的this

this.table.on('click', 'tbody tr', function (e) {
  // "this" is what you think it is
});

vs

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的作用域正确(不是窗口)。