knockout.js - Vấn đề gán TypeScript và Knockout cho 'this' - có cần hàm lambda không?
Tôi đã tạo một hàm htmlHelper sử dụng TypeScript và KnockoutJS để chỉnh sửa một danh sách email.
Danh sách email là một Knockout ObservableArray có tên emails, và tôi có một liên kết cho mỗi mục để xóa chúng. Đây là đoạn HTML:
<ul data-bind="foreach: emails" >
<li>
<a href="#" data-bind="click: $parent.deleteItem">Delete</a>
<span data-bind="text: $data"></span>
</li>
</ul>
Liên kết xóa được gắn với $parent.deleteItem đây là một phương thức trong viewmodel:
// remove item
public deleteItem(emailToDelete: string) {
// remove item from list
this.emails.remove(emailToDelete);
}
Tất cả điều này hoạt động cho đến khi phương thức deleteItem được thực thi. "this" trong phương thức này khi được gọi là phần tử trong mảng, chứ không phải mô hình view. Do đó, this.emails là một tham chiếu null và bị lỗi.
Tôi biết rằng TypeScript hỗ trợ cú pháp Lambda nhưng tôi không thể tìm thấy cách viết đúng cách cho điều này (có rất ít ví dụ trên mạng).
Hay là có một cách tiếp cận khác mà tôi có thể thử?
Câu trả lời #1
Bạn có thể có được closure đúng cho 'this' bằng cách khai báo thân phương thức bên trong constructor lớp
class VM {
public deleteItem: (emailToDelete: string) => void;
constructor() {
this.deleteItem = (emailToDelete: string) => {
// 'this' will be pointing to 'this' from constructor
// no matter from where this method will be called
this.emails.remove(emailToDelete);
}
}
}
CẬP NHẬT :
Có vẻ như kể từ phiên bản Typescript 0.9.1, bạn có thể đạt được cùng kết quả bằng cách sử dụng các trình khởi tạo trường lambda:
class VM {
public deleteItem = (emailToDelete: string) => {
this.emails.remove(emailToDelete);
}
}
Câu trả lời #2
Găng tay mọi người! Chỉ cần ràng buộc $parent như thế này:
<a href="#" data-bind="click: $parent.deleteItem.bind($parent)">Delete</a>
