contexte tapuscrit mal ce

voix
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>

Le problème est dans la méthode removeUser. Par défaut, si je ne lie pas le contexte, cette == UserToDelete - objet non viewmodel. Si j'ajoutant constructeur:this.removeUser = this.removeUser.bind(this); (manually enforce context) , puis contexte est au besoin ce viewmodel de ==, mais se plaint tapuscrit pour « Impossible de convertir fonction à ( l' utilisateur: l' utilisateur) => vide nécessite une signature d'appel, mais la fonction n'a pas un. »

Créé 07/10/2012 à 09:04
source utilisateur
Dans d'autres langues...                            


5 réponses

voix
5

Je ne suis pas familier avec ko alors peut-être il y a une meilleure façon de résoudre le changement de contexte, mais votre erreur de compilation dactylographiée est causée par « bind » renvoyant type « Fonction » qui est incompatible avec le type de « removeUser ». Vous devriez être en mesure de résoudre ce problème en jetant la fonction de retour dans la signature de type original comme suit:

this.removeUser = <(user: User) => void> this.removeUser.bind(this);
Créé 07/10/2012 à 18:33
source utilisateur

voix
2

Une alternative est de changer le clic de liaison à utiliser JavaScript de lier la fonction pour forcer la valeur thisà être votre modèle de vue: data-bind="click: $root.MyFunc.bind($root)".

Notez que $dataet le clic eventobjet sera toujours transmis comme arguments MyFuncde knock - out comme décrit par le clic liant la spécification. Si vous avez besoin de passer outre les arguments sont passés à MyFunc, les passer simplement dans la fonction de liaison après $rootcomme ceci: .bind($root, param1, param2). Techniquement, ces arguments seront préfixés aux arguments étant fournis par knock - out, donnant des arguments [param1, param2, data, event].

Créé 15/04/2014 à 21:00
source utilisateur

voix
2

Eh bien, j'eu le même problème c'est pourquoi je suis venu avec la classe de base suivante pour résoudre mon problème

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 que cela fait est boucle tous les membres de votre classe et si une méthode commence par il émet une nouvelle méthode sans pour cela appellera la méthode originale avec le contexte.

Non pas que $.proxyest un appel jquery si jquery est nécessaire pour que cela fonctionne.

Créé 05/11/2012 à 22:30
source utilisateur

voix
1

Eh bien, la solution la plus simple et ce que je fais normalement avec tapuscrit et js knock-out est que je ne déclare pas de fonctions appelées knock-out sur le prototype, mais au constructeur. Alors, je le ferais comme ceci:

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

        constructor () {
            this.users = ko.observableArray([]);
            this.removeUser = (user:User) => {
                this.users.remove(user);
            }
        }
}
Créé 08/12/2012 à 19:59
source utilisateur

voix
0

J'ai rencontré le même problème. Pour obtenir le bon contexte, vous pouvez utiliser les paramètres qui sont passés par le clickbinding. Le clickbinding passe 2 paramètres, à savoir l'utilisateur et l'événement jquery du clic.

Si vous prenez l'événement jquery, et que d'utiliser la fonction ko.contextFor (), vous pouvez obtenir le bon contexte.

Votre fonction ressemblerait à quelque chose comme:

removeUser(user: User, clickEvent: any): void {
    var self = ko.contextFor(clickEvent.srcElement).$root;
    self.users.remove(user);
}
Créé 01/02/2013 à 04:28
source utilisateur

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