Typescript context greșit acest lucru

voturi
7

Cod:

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>

Problema este în metoda removeUser. În mod implicit, dacă nu se leagă context, acest == UserToDelete - obiect nu viewModel. Dacă am adăugarea la constructor: this.removeUser = this.removeUser.bind(this); (manually enforce context), atunci context , este necesar ca acest viewmodel ==, dar apoi typescript se plânge pentru „Nu se poate converti la funcții. (Utilizator: Utilizator) => void necesită un apel de semnături, dar funcția îi lipsește unul“

Întrebat 07/10/2012 la 09:04
sursa de către utilizator
În alte limbi...                            


5 răspunsuri

voturi
5

Nu sunt familiarizați cu ko astfel încât, probabil, există o modalitate mai bună de a rezolva comutarea contextului, dar eroarea compilator dactilografiat este cauzată de „bind“ se întoarce de tip „funcție“, care este incompatibil cu tipul de „removeUser“. Ar trebui să fie în măsură să rezolve acest lucru prin turnare funcția sa întors în semnătura de tip original, după cum urmează:

this.removeUser = <(user: User) => void> this.removeUser.bind(this);
Publicat 07/10/2012 la 18:33
sursa de către utilizator

voturi
2

O alternativă este de a schimba legarea de a utiliza JavaScript este clicul leagă funcția de a forța valoarea thissă fie modelul dvs. de vedere: data-bind="click: $root.MyFunc.bind($root)".

Rețineți că $datași faceți clic pe eventobiectul va fi în continuare transmise ca argumente pentru a de MyFuncla knock - out așa cum este descris de legare click caietul de sarcini. Dacă aveți nevoie pentru a trece peste argumentele pasate MyFunc, pur și simplu trece - le în funcția de legare după $rootastfel: .bind($root, param1, param2). Punct de vedere tehnic, aceste argumente vor fi prefixate la argumentele fiind furnizate prin knock - out, oferind argumente [param1, param2, data, event].

Publicat 15/04/2014 la 21:00
sursa de către utilizator

voturi
2

Ei bine, am avut aceeași problemă thats de ce am venit cu următoarea clasă de bază pentru a rezolva problema mea

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

ce acest lucru nu este în buclă toți membrii clasei, iar dacă o metodă începe cu On acesta va crea o nouă metodă fără On, care va apela metoda originală cu contextul potrivit.

Nu că $.proxyeste un apel , astfel jQuery jQuery este necesar pentru ca aceasta să funcționeze.

Publicat 05/11/2012 la 22:30
sursa de către utilizator

voturi
1

Ei bine, cea mai simplă soluție și ceea ce fac în mod normal, cu dactilografiat și knock-out este că js eu nu declar funcții numite de knock-out pe prototip, dar la constructor. Deci, aș face așa:

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

        constructor () {
            this.users = ko.observableArray([]);
            this.removeUser = (user:User) => {
                this.users.remove(user);
            }
        }
}
Publicat 08/12/2012 la 19:59
sursa de către utilizator

voturi
0

Am fugit în aceeași problemă. Pentru a obține contextul potrivit, puteți utiliza parametrii care sunt transmise de clickbinding. Clickbinding trece 2 parametri, de exemplu, utilizatorul și evenimentul jQuery clicului.

Dacă luați evenimentul jquery, și decât folosiți funcția ko.contextFor (), puteți obține contextul potrivit.

Funcția dvs. ar arata ceva de genul:

removeUser(user: User, clickEvent: any): void {
    var self = ko.contextFor(clickEvent.srcElement).$root;
    self.users.remove(user);
}
Publicat 01/02/2013 la 04:28
sursa de către utilizator

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