Maszynopis niewłaściwy kontekst tego

głosy
7

Kod:

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>

Problem polega na sposobie RemoveUser. Domyślnie, jeśli nie wiążą się kontekst, to == UserToDelete - nie ViewModel obiekt. Gdybym dodanie do konstruktora: this.removeUser = this.removeUser.bind(this); (manually enforce context), a następnie jako kontekst jest potrzebne to == ViewModel, ale potem maszynopis narzeka na „nie można przekonwertować do funkcji. (Użytkownika: Użytkownik) => void wymaga do podpisów połączeń, ale brakuje jednego Funkcja”

Utwórz 07/10/2012 o 09:04
źródło użytkownik
W innych językach...                            


5 odpowiedzi

głosy
5

Nie jestem zaznajomiony z ko więc być może istnieje lepszy sposób na rozwiązanie przełączania kontekstu, ale twój błąd kompilatora maszynopis jest spowodowany przez „wiążą” powracającego typu „funkcja”, co jest niezgodne z typem „RemoveUser”. Powinieneś być w stanie rozwiązać ten problem poprzez odlewanie funkcję zwrócony w oryginalnym podpisem typu w następujący sposób:

this.removeUser = <(user: User) => void> this.removeUser.bind(this);
Odpowiedział 07/10/2012 o 18:33
źródło użytkownik

głosy
2

Alternatywą jest zmiana kliknięcie wiązania można wykorzystać JavaScript za powiązania funkcji wymusić wartość thisza swoją Widok Model: data-bind="click: $root.MyFunc.bind($root)".

Należy pamiętać, że $datai kliknij eventobiekt nadal będą przekazywane jako argumenty MyFuncz Knockout opisany przez wiązania click specyfikacji. Jeśli trzeba zastąpić argumenty są przekazywane do MyFuncwystarczy przekazać je do funkcji wiązania po $roottak: .bind($root, param1, param2). Technicznie rzecz biorąc, te argumenty będzie dołączany do argumentów dostarczane przez nokaut, podając argumenty [param1, param2, data, event].

Odpowiedział 15/04/2014 o 21:00
źródło użytkownik

głosy
2

Cóż miałem ten sam problem, to dlaczego ja przyszedłem z poniższej klasy bazowej, aby rozwiązać mój problem

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 robi pętlę, wszyscy członkowie twojej klasy i jeśli metoda rozpoczyna On stworzy nową metodę bez Wł która będzie nazywać oryginalną metodę z właściwym kontekście.

Nie dlatego, że $.proxyjest to wezwanie jquery jquery tak jest potrzebne do tego, aby pracować.

Odpowiedział 05/11/2012 o 22:30
źródło użytkownik

głosy
1

Cóż, najprostszym rozwiązaniem, a co zwykle zrobić z maszynopisu i pucharowej js jest to, że nie deklaruje funkcje wywoływane z nokautem na prototypie, ale w konstruktorze. Tak, chciałbym zrobić to tak:

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

        constructor () {
            this.users = ko.observableArray([]);
            this.removeUser = (user:User) => {
                this.users.remove(user);
            }
        }
}
Odpowiedział 08/12/2012 o 19:59
źródło użytkownik

głosy
0

Wpadłem na ten sam problem. Aby uzyskać odpowiedni kontekst można użyć parametrów, które są przekazywane przez clickbinding. Clickbinding przechodzi 2 parametry, tj użytkownikiem i zdarzenia jquery do kliknięcia.

Zażycie zdarzenia jquery i nie korzystać z funkcji ko.contextFor (), można uzyskać odpowiedniego kontekstu.

Twoja funkcja będzie wyglądać następująco:

removeUser(user: User, clickEvent: any): void {
    var self = ko.contextFor(clickEvent.srcElement).$root;
    self.users.remove(user);
}
Odpowiedział 01/02/2013 o 04:28
źródło użytkownik

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