Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
486 views
in Technique[技术] by (71.8m points)

knockout.js - TypeScript and Knockout binding to 'this' issue - lambda function needed?

I've been creating a htmlHelper function using TypeScript and KnockoutJS to edit a list of emails.

The list of emails is a Knockout ObservableArray called emails, and I have a link against each item to delete them. This is the HTML fragment:

<ul data-bind="foreach: emails" >
    <li>
        <a href="#" data-bind="click: $parent.deleteItem">Delete</a>
        &nbsp;<span data-bind="text: $data"></span>
    </li>
</ul>

The delete link is bound to $parent.deleteItem this is a method in the viewmodel:

// remove item
public deleteItem(emailToDelete: string) {
    // remove item from list
    this.emails.remove(emailToDelete);
}

This all works until the deleteItem method is executed. The "this" in this method when it is called is the item in the array, and not the view model. Hence this.emails is a null reference and fails.

I know that TypeScript supports the Lambda syntax but I can't find the right way to write this (there few examples out there).

Or is there a different approach I could take?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can get correct closure for 'this' by declaring method body inside class constructor

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

UPDATE:

It seems that since Typescript ver 0.9.1 you can achieve the same result by using lambda field initializers:

class VM {
    public deleteItem = (emailToDelete: string) => {
        this.emails.remove(emailToDelete);
    }        
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...