0
function ObjectProvider() {
    this.url = "ajax/inbounds.php"
    this.inBounds = function () {
        this.removeMarkers();
        var url_string = this.url;
        $.getJSON(url_string, function (data) {
            for (i = 0; i != data.length; ++i) {
                this.createObject(data[i]);
            }
        });
    };
    this.createObject = function (_data) {};
    this.removeMarkers = function () {};
};

だからライン

this.createObject( data[i] );

いくつかの問題がありますが

this.removeMarkers();

正常に動作します。

どちらの関数もObjectProviderオブジェクトで定義されています。test()という関数を追加しようとしましたが、JSONコールバック関数内で呼び出されるものが気に入らないだけです。

4

4 に答える 4

4

これは典型的なスコーピングの問題です。コールバック関数のthis内部$.getJSON()は、もはや同じではありませんthis

この問題を解決するには、 を呼び出す前に への参照を保持する必要がありますthis$.getJSON()

var self = this;
$.getJSON(url_string, function(data) {
    // self.createObject( data[i] );
});

または、次を使用して成功コールバック関数をバインドします$.proxy

$.getJSON(url_string, $.proxy(function(data) {
    this.createObject(data[i]);
}, this));
于 2012-06-04T07:57:56.527 に答える
1

thisajax コールバックの は別のコンテキストにあります。

解決策:ローカル変数にキャッシュします。

this.inBounds = function(){
    var self = this;
    self.removeMarkers();
    var url_string = this.url;
    $.getJSON(url_string, function(data) {
        for( i=0; i != data.length; ++i ){
            self.createObject( data[i] );
        }
    });
};
于 2012-06-04T07:57:28.830 に答える
0

getJSON私はこの理由で好きではありません、それはに比べて制限が多すぎajaxます。

基本的に、success関数が実行されると、インスタンスthisをポイントしなくなりますObjectProvider。これを解決するには、代わりにajaxcontextを使用して、便利なプロパティを提供します。

function ObjectProvider(){
  this.url = "ajax/inbounds.php"
  this.inBounds = function(){
    this.removeMarkers();

    var url_string = this.url;
    $.ajax({
      url: this.url,
      dataType: "json",
      context: this,
      success: function(data) {
        for( i=0; i != data.length; ++i ){
            this.createObject( data[i] );
        }
    });
  };

  this.createObject = function(_data){};
  this.removeMarkers = function(){};
};

それ以外の場合は、 bindを使用できます:

$.getJSON(url_string, function(data) {
    for( i=0; i != data.length; ++i ){
        this.createObject( data[i] );
    }
}.bind(this));

特定のコンテキストオブジェクトに「バインド」された新しい関数を作成するため。ただし、ES5をサポートしている、またはそのためのシムを備えているブラウザーでのみ(上記のリンクで説明されているように)。

言及されたバージョン、インスタンスを格納するためのクロージャーもありますが、私は個人的に、厳密に必要でない場合はそれを避けることを好みます。今日、この種の行動については、それは古い慣習と見なされています。

そして、クロージャーについて話します。コンストラクター内で関数を宣言する必要はありません。このようにして、それらは常に動的に追加され、一部の内部変数にアクセスしていない場合、理由がない場合は、リソースの浪費にすぎません。明確にするために、あなたの場合、あなたが持っているなら:

var a = new ObjectProvider();
var b = new ObjectProvider();

console.log(a.createObject === b.createObject) // false

より良いアプローチは次のとおりです。

function ObjectProvider() {
}

ObjectProvider.prototype = {
    constructor: ObjectProvider,

    url: "ajax/inbounds.php",

    inBounds: function () { /* ... */ },
    createObject: function () { /* ... */ },
    removeMarkers: function () { /* ... */ }         
}

var a = new ObjectProvider();
var b = new ObjectProvider();

console.log(a.createObject === b.createObject) // true

ただし、その時点で、動的プロパティがない場合(たとえば、URLが常に同じで、パラメーターとしてコンストラクターに渡されない場合)、別のインスタンスを用意する必要がない可能性があります。ちょうどそして上へ:

var ObjectProvider = {
    url: "ajax/inbounds.php",

    inBounds: function () { /* ... */ },
    createObject: function () { /* ... */ },
    removeMarkers: function () { /* ... */ }         
};

そして、それを「シングルトン」として使用します。

ObjectProvider.createObject()
于 2012-06-04T08:57:41.960 に答える
0

問題は、関数を getJSON に渡していることです。その関数は、グローバル オブジェクトまたは jQuery によって定義されたカスタム オブジェクトのいずれかを指す「this」で呼び出されます。コールバック内の「this」がオブジェクトを指すようにする場合は、bind メソッドを使用します (一部の古いブラウザーでは使用できませんが、このメソッドをエミュレートするプロジェクトを簡単に見つけることができます)。

$.getJSON(url_string, function(data) {
    for( i=0; i != data.length; ++i ){
        this.createObject( data[i] );
    }
}.bind(this));

または、このコールバックの外側で「this」を指すヘルパー変数を定義し、その変数を内側で使用します。

var self = this;

$.getJSON(url_string, function(data) {
    for( i=0; i != data.length; ++i ){
        self.createObject( data[i] );
    }
});
于 2012-06-04T07:58:20.700 に答える