5

TypeScriptは確かにJavaScriptであるため、TypeScriptコンパイラは昔ながらのJavaScriptに忠実であり続けようとしていることに気づきました。ただし、Intellisenseが「this」キーワードとして解釈するものと、実行時に実際に解決されるものとの間には、断絶があります。たとえば、次のTypeScriptajax呼び出しについて考えてみます。

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

        }

およびそれに対応するコールバック:

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

ここで、TypeScriptソースファイル内のonGetAgenciesCompleteの行 "var self = this"にカーソルを合わせると、変数 "self"のIntellisense定義は、それがタイプHomePageViewModelBaseであることを示します。ここで、HomePageViewModelBaseは上記のメソッドを含むクラスです。

前述のように生成されたJavascriptは次のとおりです。

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

これは、HomePageViewModelBase.prototype.onGetAgenciesCompleteで変数「self」を実行すると、HomePageViewModelBaseのインスタンスではなく、AjaxContextのように解決されます。これは予想される動作ですか、それともバグとして報告する必要がありますか?

4

2 に答える 2

6

はい、おそらくオブジェクト自体を参照することを意図してthisいるため、バグとして報告する必要があります。$.ajax()$.ajax()

それが機能するようにそれを回避したい場合は、成功関数を次のように変更します。

success: self.onGetAgenciesComplete

または、クラスを表すために、$。ajaxのコンテキストメソッドを使用するだけです。this

$.ajax({ 
    context: this,
    // now *this* will come from the previous scope,
    // which in your case, is your class "HomePageViewModelBase"

    // now that we know for certain what -this- refers to
    success: this.onGetAgenciesComplete
});
于 2012-10-31T13:52:08.230 に答える
3

(Intellisenseを含む)静的分析に関する限り、のコンテキストはonGetAgenciesComplete 常に HomePageViewModelBaseそうです。ただし、実行時に、明示的な内部jQuery.ajaxコンテキストバインディングを介してコンテキストが動的に設定されます。Intellisenseがコンテキストが動的に変化することを判断できる唯一の方法は、実際にそのコードパスを実行することですが、それでもあいまいさが生じます。どのコンテキストが適切なコンテキストですか。

1回限りの呼び出しで、他の場所でメソッドを「借用」した場合はどうなりますか?次に、Intellisenseはその呼び出しサイトを使用してコンテキストを決定する必要がありますか?おそらくそうではありません...

HomePage.prototype.onGetAgencies.call({ some other context }, ...);

(読みやすさのために短縮されています。)

于 2012-11-01T17:04:21.600 に答える