Strojopisem špatný kontext této

hlasů
7

Kód:

export class ViewModel {
        public users: knockout.koObservableArrayBase;

        constructor () {
            this.users = ko.observableArray([]);
            this.removeUser = this.removeUser.bind(this);//<-- Here compiller shows error
        }

        removeUser(user: User): void {
            this.users.remove(user);
        }
}

html:

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Surname</th>
        </tr>
    </thead>
    <tbody data-bind=foreach: users>
        <tr>
            <td><a href=# data-bind=click: $root.removeUser>Remove</a></td>
            <td data-bind=text: name></td>
            <td data-bind=text: surname></td>
        </tr>
    </tbody>
</table>

Problém je v metodě removeUser. Ve výchozím nastavení, pokud se nevážou kontext, tento == UserToDelete - ne viewmodel objekt. Mám-li přidat do konstruktoru: this.removeUser = this.removeUser.bind(this); (manually enforce context), potom kontext je v případě potřeby tento == viewmodel, ale pak strojopisem si stěžuje na „Nelze převést funkce k. (Uživatel: User) => void vyžaduje podpisy volání, ale funkce postrádá jednu“

Položena 07/10/2012 v 09:04
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
5

Nejsem obeznámen s ko, takže je snad lepší způsob, jak vyřešit přepínání kontextu, ale vaše chyba kompilátoru strojopis je způsobena ‚váží‘ vracející typ ‚funkcí‘, která je neslučitelná s typem ‚removeUser‘. Měli byste být schopni to vyřešit tím, že obsadí vrácené funkce do původního podpisu typu takto:

this.removeUser = <(user: User) => void> this.removeUser.bind(this);
Odpovězeno 07/10/2012 v 18:33
zdroj uživatelem

hlasů
2

Alternativním řešením je změnit kliknutím závaznou používat JavaScript je vázaný funkce vynutit hodnotu thisza svůj model view: data-bind="click: $root.MyFunc.bind($root)".

Všimněte si, že $datai kliknutím eventobjekt se bude předán jako argumenty MyFuncz Knockout, jak je popsáno podle závazného click specifikaci. Pokud potřebujete přepsat argumenty byly předány MyFunc, jednoduše předat je do funkce vazby poté, co $rootjako tak: .bind($root, param1, param2). Z technického hlediska se tyto argumenty se prepended na argumenty zásobovaná Knockout, dávat argumenty [param1, param2, data, event].

Odpovězeno 15/04/2014 v 21:00
zdroj uživatelem

hlasů
2

Tak jsem měl stejný problém to je důvod, proč jsem přišel s následující základní třídy opravit můj problém

export class ViewModelBase {
    private prefix: string = 'On';

    public Initialize() {
        for (var methodName in this) {
            var fn = this[methodName];
            var newMethodName = methodName.substr(this.prefix.length);
            if (typeof fn === 'function' && methodName.indexOf(this.prefix) == 0 && this[newMethodName] == undefined) {
                this[newMethodName] = $.proxy(fn, this);
            }
        }
    }
}

co to dělá, je tvořit všichni členové vaší třídě a v případě, že metoda začíná na něm vytvoří novou metodu, aniž by o tom bude volat původní metodu s správném kontextu.

Ne, že $.proxyje jquery hovor tak jQuery je potřeba pro tuto práci.

Odpovězeno 05/11/2012 v 22:30
zdroj uživatelem

hlasů
1

No, nejjednodušší řešení, a to, co jsem normálně dělat s psacím stroji a knockout js je, že nemám deklarovat funkce volat z knockout na prototypu, ale v konstruktoru. Takže bych, aby to takhle:

export class ViewModel {
        public users: knockout.koObservableArrayBase;
        removeUser:(user: User) => void;

        constructor () {
            this.users = ko.observableArray([]);
            this.removeUser = (user:User) => {
                this.users.remove(user);
            }
        }
}
Odpovězeno 08/12/2012 v 19:59
zdroj uživatelem

hlasů
0

Běžel jsem do stejného problému. Chcete-li získat ten správný kontext, můžete použít parametry, které jsou předávány podle clickbinding. Clickbinding prochází 2 parametry, tj uživatele a jQuery události kliknutí.

Pokud budete mít událost jQuery, a pak použijte funkci ko.contextFor (), můžete získat ten správný kontext.

Vaše funkce bude vypadat nějak takto:

removeUser(user: User, clickEvent: any): void {
    var self = ko.contextFor(clickEvent.srcElement).$root;
    self.users.remove(user);
}
Odpovězeno 01/02/2013 v 04:28
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more