0

動的に生成され、特定の数 (ユーザーが動的に定義) の高度な散布図を含むページがあります。散布図自体を定義する JavaScript オブジェクトを作成するつもりです。つまり、いくつかのパラメーター、データ、およびコンテナー ID を受け取り、視覚化を取得するために必要なさまざまな要素 (キャンバス要素、ツールバーなど) を作成します。そうするために、次の(簡略化された)クラスから始めました。

(function () {
    if (!this.namespace) { this.namespace = {};}

    this._instances = { index: 0 };

    this.namespace.ScatterPlot = function (containerId, file, options) {
        _instances.index ++;
        this.id          = this.containerId+"-"+_instances.index ;
        this.containerId = containerId ;
        _instances [this.id] = this;

        // ... Do stuffs with file and options ...

        // Initialize elements once the DOM is ready
        $(this.updateDOM);
    }

    namespace.ScatterPlot.prototype = {
        updateDOM: function() {
            $("<canvas>")
                .click(clickCallback)
                .appendTo("#"+this.containerId);
            //(...)
        },

        clickCallback: function() {
            alert("Some click: "+this.id);
        }
    }


})();

各オブジェクトは次の方法で作成できます。

var v1 = new namespace.ScatterPlot("container1", "foo", "foo");
var v2 = new namespace.ScatterPlot("container2", "foo", "foo");

ここには 2 つの問題があります。(1) updateDOM では、「this」は最初の ScatterPlot オブジェクトを参照しません。つまり、この例は機能しません。(2) 同様に、clickCallback は散布図を参照できません。 「これ」か。

私は JavaScript を初めて使用しますが、JavaScript での OO プログラミングのロジックを理解するのにまだ苦労しているので、問題は次のとおりです。掘り下げた後、これをupdateDOMに渡すことで、おおよそ目的を達成できました。

$(this.updateDOM(this)); // This blows my eyes but does the trick, at least partially

updateDOM: function(that) {
    $("<canvas>")
        .click(that.clickCallback)
        .appendTo("#"+that.containerId);
    //(...)
},

clickCallback: function() {
    // Not working either... Should pass 'that' to the function too
    alert("Some click: "+this.id);
}

しかし、私はこのパターンが非常に洗練されているとは感じていません...そしてクリックコールバックに関しても問題は修正されていません。

考え?

4

1 に答える 1

2

MDN のキーワードの紹介をご覧thisください。

その問題に対処する標準的な方法は、that変数を使用することです-引数としてではなく、別の関数で:

var that = this;
$(function() {
    that.updateDOM();
});

// or

$(this.getClickCallback());
...
namespace.ScatterPlot.prototype.getClickCallback =  function() {
    var that = this;
    return function clickCallback(e) {
        alert("Some click: "+that.id);
    };
};

別の方法として、2 番目の例がより一般的な方法で行うこととまったく同じことを行う.bind()(または古いブラウザーの場合) をいつでも使用できます。$.proxy

$(this.clickCallback.bind(this));
于 2012-11-20T13:59:08.147 に答える