1

次のように大まかにレイアウトされたライブラリを構築しています。いくつかの変数、イベント ハンドラー、および関連するイベントを発生させるメソッドがあります。最後に、物件との契約を延長します。これは次のようになります (///...他のコードを切り取った場所にいくつか追加しました)。

$.collidR = function (options) {

  /// ...

  var hubName = 'CollidRHub';
  var hubProxy = connection.createHubProxy(hubName);   

  /// ...

  hubProxy.on('registrationComplete', function (username, hasChanges) {
      $(window).triggerHandler(events.onRegistrationComplete, { username: username, hasChanges: hasChanges });
      log(username + " has successfully registered for this entity.");

      // capture current user 
      this._currentUser = username;

      // hook for catching up when user joins after edits
      if (hasChanges) {
          log("There are outstanding changes for this entity...");

      }
  }); 

  /// ...

  this.registerClient = function () {
      /// does some stuff that makes registrationComplete fire
      /// ...
  };

};

Object.defineProperty($.collidR.prototype, "currentUser", {
    get: function () {
        return this._currentUser ? this._currentUser : "";
    }
});

上記のthis._currentUser = usernameビットは機能しないように見えることに注意してください。それはカプセル化の問題だと思います。これは、この質問が目指しているものです。

別の関連ライブラリで のインスタンスを作成collidRし、イベントに応答する必要があります。そのためのハンドラーを次のように設定しました。

$(window).on(collidR.events.onEditorsUpdated, function (e, data) {

  /// ...

  users.forEach(function (user) {
      var currentUser = collidR.currentUser;

      // here, currentUser is always default of ""
      if (user != currentUser) {
          /// ...
      }
  });

});

これが私が見ているものです:

  1. イベントが発生し、ハンドラーregistrationCompleteが正常に呼び出される
  2. デバッガーからthis._currentUserは、値が設定される前は未定義です
  3. this._currentUser = usernameが実行され、値が設定されます
  4. onEditorsUpdatedイベントが発生すると、常にcollidR.currentUserハンドラーのデフォルト値 (空の文字列) になります。

順不同に感じるのは、オブジェクトの残りの部分の後で、プロパティを定義する場所です。プロパティを参照しようとするメソッドを定義した後で、オブジェクトのプロトタイプを変更しているようです...これは正しくありません。

私もthis.currentUser(内部メソッドで)試しましたが、同じ結果が得られました。

内部メソッドが呼び出される前にプロトタイプが拡張された場合、それを行ったときにvar currentUser = collidR.currentUser;プロパティから値を取得すると想定していましたが、それは常に空の文字列です。

物件を早く登録する方法はありますか?

公開されたプロパティを介して後でアクセスできるように、値を設定する正しい方法はありますか?

4

1 に答える 1

5

あなたが思っているようなものthisではないからです。JavaScriptthis._currentUser = username;の の値は、関数がどのように呼び出されたかによって異なります。thisハンドラー内で、hubProxyまたは 以外の他のオブジェクトを参照していると思いますcollidR

thisプラグイン全体が参照していると仮定するとcollidR(この後のセクションで説明されているように、そうではない可能性が非常に高いと思われます)、できることは、そのスコープのコンテキストをハンドラーの外部の別の変数に保存することです。そうすれば、その変数を介して外側のスコープのコンテキストを参照できます。

// Saving this scope's context
var that = this;

hubProxy.on('registrationComplete', function (username, hasChanges) {

  // access _currentUser via the saved context
  that._currentUser = username;

});

ただし、 の使用について警告する必要がありますthis。プラグインを作成していると仮定すると、 のように呼び出します$.collidR({..})。この場合、this関数の内部が参照され$(jQuery であると仮定します)、いくつかのプロパティをライブラリにアタッチしています。衝突が発生する可能性があるため、プラグイン固有の値をグローバル ライブラリにアタッチするのは危険です。

代わりに、ローカル変数/オブジェクト内に保存することをお勧めします。

于 2013-10-15T04:40:53.933 に答える