Typoskript falschen Kontext dieser

stimmen
7

Code:

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>

Das Problem ist in RemoveUser Methode. In der Standardeinstellung , wenn ich Kontext nicht binden, diese == UserToDelete - nicht Viewmodel - Objekt. Wenn ich Konstruktor hinzu: this.removeUser = this.removeUser.bind(this); (manually enforce context), dann wird Kontext dieses == Ansichtsmodell benötigt, aber dann klagt Typoskript für „umwandeln kann nicht Funktion zu. (User: Benutzer) => void einen Anruf Signaturen erfordert, aber Funktion fehlt eine“

Veröffentlicht am 07/10/2012 um 09:04
quelle vom benutzer
In anderen Sprachen...                            


5 antworten

stimmen
5

Ich bin nicht vertraut mit ko so vielleicht gibt es einen besseren Weg, um den Kontextwechsel, aber Ihre Typoskript Compiler-Fehler zu lösen, ist durch ‚binden‘ Rückkehr Typ ‚Funktion‘ verursacht, die mit der Art des ‚RemoveUser‘ unvereinbar ist. Sie sollten dieses Problem zu lösen, indem er die zurück Funktion in der ursprünglichen Art Signatur Gießen wie folgt:

this.removeUser = <(user: User) => void> this.removeUser.bind(this);
Beantwortet am 07/10/2012 um 18:33
quelle vom benutzer

stimmen
2

Eine Alternative ist , den Klick zu ändern Bindung von JavaScript zu verwenden , bindet Funktion den Wert zu zwingen , thisIhre Ansicht Modell zu sein: data-bind="click: $root.MyFunc.bind($root)".

Beachten Sie, dass $dataund das Klick - eventObjekt wird noch in als Argumente übergeben werden MyFuncvon Knockout wie durch die beschriebene Klick verbindlich Spezifikation. Wenn Sie die Argumente außer Kraft setzen müssen, werden übergeben MyFunc, sie einfach in die bind - Funktion übergeben , nachdem $rootetwa so: .bind($root, param1, param2). Technisch gesehen , werden diese Argumente werden vorangestellt , auf die Argumente durch Knockout geliefert, unter Angabe von Gründen [param1, param2, data, event].

Beantwortet am 15/04/2014 um 21:00
quelle vom benutzer

stimmen
2

Nun, ich hatte das gleiche Problem thats, warum ich mit der folgenden Basisklasse kam zu meinem Problem zu beheben

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

Was dies bedeutet ist Schleife alle Mitglieder Ihrer Klasse und wenn eine Methode mit beginnt an wird es eine neue Methode ohne On erstellen, die die ursprüngliche Methode mit dem richtigen Kontext nennen.

Nicht , dass $.proxyist ein jquery Anruf so jquery benötigt wird , damit dies funktioniert.

Beantwortet am 05/11/2012 um 22:30
quelle vom benutzer

stimmen
1

Nun, die einfachste Lösung, und das, was ich normalerweise tun mit Typoskript und Knockout js ist, dass ich nicht ausdrücklich erklären, von Knockout auf dem Prototyp namens Funktionen aber an dem Konstruktor. So würde ich es so machen:

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

        constructor () {
            this.users = ko.observableArray([]);
            this.removeUser = (user:User) => {
                this.users.remove(user);
            }
        }
}
Beantwortet am 08/12/2012 um 19:59
quelle vom benutzer

stimmen
0

Ich lief in das gleiche Problem. Um den richtigen Kontext zu erhalten können Sie die Parameter verwenden, das von dem clickbinding übergeben werden. Das clickbinding geht 2 Parameter, dh den Benutzer und das jquery Ereignis des Klicks.

Wenn Sie das jquery Ereignis nehmen, und als die ko.contextFor () Funktion verwenden, können Sie den richtigen Kontext erhalten.

Ihre Funktion würde in etwa so aussehen:

removeUser(user: User, clickEvent: any): void {
    var self = ko.contextFor(clickEvent.srcElement).$root;
    self.users.remove(user);
}
Beantwortet am 01/02/2013 um 04:28
quelle vom benutzer

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