Mi rendo conto che il compilatore TypeScript sta tentando di rimanere fedele al semplice JavaScript vecchio, poiché TypeScript è effettivamente JavaScript. Tuttavia, vi è una disconnessione tra ciò che Intellisense interpreta come la parola chiave "this" e ciò che effettivamente risolve durante il runtime. Ad esempio, si consideri la seguente chiamata dattiloscritto ajax:
getAgencies() {
var self = this;
$.ajax(liveString + "/Home/GetSupportedAgencies",
{
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
error: Utilities.Logger.displayAjaxError,
success: this.onGetAgenciesComplete
});
}
e il suo corrispondente callback:
onGetAgenciesComplete(agencies) {
var self = this;
if (agencies == null)
Utilities.Logger.displayErrorOnLogConsole("There was an error retrieving supported agencies. Refresh site and try again.");
else {
$.each(agencies, function (i, a) {
self._indexViewModel.agencies.push({ name: a.Name, fullName: a.FullName, shortName: a.ShortName, bbox: a.BBox, countryCode: a.CountryCode });
});
if (Modernizr.geolocation) {
navigator.geolocation.getCurrentPosition(
function (position) {
self.initMapPage(position, self);
},
function (error) {
Utilities.Logger.displayErrorOnLogConsole("Oops, we could not get your location at his time. Please try later.");
});
}
else {
Utilities.Logger.displayErrorOnLogConsole("Sorry, your browser does not return location information.");
self.getBusRoutes(self.agencyName);
}
// end of initialization
}
}
Ora, quando mi passa il mouse sopra la linea "var sé = presente" nel onGetAgenciesComplete all'interno del file sorgente dattiloscritto, la definizione Intellisense della variabile "self" indica che è di tipo HomePageViewModelBase, dove HomePageViewModelBase è la classe che contiene i metodi precedenti.
Il Javascript generato per citato è il seguente:
HomePageViewModelBase.prototype.getAgencies = function() {
var self = this;
$.ajax(liveString + "/Home/GetSupportedAgencies", {
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
error: Utilities.Logger.displayAjaxError,
success: this.onGetAgenciesComplete
});
};
HomePageViewModelBase.prototype.onGetAgenciesComplete = function (agencies) {
var self = this;
if(agencies == null) {
Utilities.Logger.displayErrorOnLogConsole("There was an error retrieving supported agencies. Refresh site and try again.");
} else {
$.each(agencies, function (i, a) {
self._indexViewModel.agencies.push({
name: a.Name,
fullName: a.FullName,
shortName: a.ShortName,
bbox: a.BBox,
countryCode: a.CountryCode
});
});
if(Modernizr.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
self.initMapPage(position, self);
}, function (error) {
Utilities.Logger.displayErrorOnLogConsole("Oops, we could not get your location at his time. Please try later.");
});
} else {
Utilities.Logger.displayErrorOnLogConsole("Sorry, your browser does not return location information.");
self.getBusRoutes(self.agencyName);
}
}
};
che, se eseguito "auto" variabile in HomePageViewModelBase.prototype.onGetAgenciesComplete viene risolto in quello che sembra un AjaxContext e non un'istanza di HomePageViewModelBase. È questo comportamento previsto o dovrei segnalarlo come un bug?
Buona risposta - l'impostazione del contesto funziona. Prima di inviare un bug, considera questa domanda: come può il compilatore inferire correttamente il contesto di 'this' quando la funzione può essere chiamata in molti contesti diversi. Credo che mostri il contesto corretto basato sull'ipotesi che la funzione sia chiamata direttamente, piuttosto che nel contesto di un callback da un'altra parte. – Fenton
Sono d'accordo, e semmai è una buona pratica (se non altro che per la leggibilità) rendere ovvio quale dovrebbe essere il contesto di "questo". Penso che il punto di @ KNji fosse, non dovrebbe sapere che è il '$ .ajax' stesso, dal momento che è così che funziona all'interno di jQuery? –
@mcpDESIGNS, questa è una buona spiegazione, grazie. Non ho mai saputo del contesto $ .ajax che è una soluzione ancora migliore. Doppio grazieHai anche ragione nel punto del mio post che intellisense non avrebbe dovuto riferirsi a "questo" in $ .ajax a un'istanza di HomePageViewModel base. –