Typescript verkeerde context dit

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

Het probleem is in removeUser methode. Standaard, als ik niet context binden, deze == UserToDelete - niet ViewModel object. Als ik toe te voegen aan bouwer: this.removeUser = this.removeUser.bind(this); (manually enforce context), dan context wordt als dit nodig had == viewmodel, maar dan typoscript klaagt voor Kan functie niet om te zetten. (Gebruiker: User) => leegte vereist een oproep handtekeningen, maar functie ontbreekt één

De vraag is gesteld op 07/10/2012 om 09:04
bron van user
In andere talen...                            


5 antwoorden

stemmen
5

Ik ben niet bekend met ko dus misschien is er een betere manier om de context switching op te lossen, maar uw typoscript compiler fout wordt veroorzaakt door 'bind' terug te keren het type 'Function' die onverenigbaar is met de aard van de 'removeUser'. Je moet in staat zijn om dit op te lossen door het gieten van de geretourneerde functie in het oorspronkelijke type handtekening als volgt:

this.removeUser = <(user: User) => void> this.removeUser.bind(this);
antwoordde op 07/10/2012 om 18:33
bron van user

stemmen
2

Een alternatief is om de klik te binden aan JavaScript gebruiken veranderen binden functie om de waarde van de te dwingen thisom de weergave model: data-bind="click: $root.MyFunc.bind($root)".

Merk op dat $datade click eventobject nog steeds worden doorgegeven als argumenten MyFuncvan Knockout zoals door de klik binding specificatie. Als u nodig hebt om de argumenten die worden doorgegeven om het te forceren MyFunc, gewoon passeren ze in de bind functie na $rootals volgt: .bind($root, param1, param2). Technisch wordt deze argumenten worden voorgevoegd de argumenten afnemen van Knockout, waarbij argumenten [param1, param2, data, event].

antwoordde op 15/04/2014 om 21:00
bron van user

stemmen
2

Nou ik had het zelfde probleem Dat is waarom ik kwam met de volgende basisklasse aan mijn probleem op te lossen

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

Wat dit doet is lus alle leden van de klasse en als een methode begint met On zal het een nieuwe methode, zonder op dat de oorspronkelijke methode met de juiste context zal roepen creëren.

Niet dat $.proxyis een jQuery oproep dus jQuery is nodig om dit te laten werken.

antwoordde op 05/11/2012 om 22:30
bron van user

stemmen
1

Welnu, de eenvoudigste oplossing en wat ik normaal gesproken niet met typoscript en knock-out js is dat ik geen functies aangeroepen vanuit knock-out op het prototype, maar bij de constructeur verklaren. Dus, ik zou het te maken als deze:

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

        constructor () {
            this.users = ko.observableArray([]);
            this.removeUser = (user:User) => {
                this.users.remove(user);
            }
        }
}
antwoordde op 08/12/2012 om 19:59
bron van user

stemmen
0

Ik liep in het zelfde probleem. Om de juiste context te krijgen kunt u de parameters die worden doorgegeven door de clickbinding gebruiken. De clickbinding passeert 2 parameters, de gebruiker en jQuery Bij de klik.

Als u de jQuery gebeurtenis te nemen, en dan gebruik maken van de functie ko.contextFor (), kunt u de juiste context te verkrijgen.

Je functie zou iets als volgt uitzien:

removeUser(user: User, clickEvent: any): void {
    var self = ko.contextFor(clickEvent.srcElement).$root;
    self.users.remove(user);
}
antwoordde op 01/02/2013 om 04:28
bron van user

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