0

私はアプリケーションに取り組んでおり、次のようなことをしていました:

dojo.ready(
           function(){ require['dojo/parser','dijit/registry','dojo/on'],function(.....){
           //find a dijit and wrap it in event handling code.});

Dojo が既に使用されている ID を持つウィジェットを登録しようとしていることを示すエラーが発生していました。問題を解決するために、次のコード行を入力しました。

           //before finding the dijit destroy the existing registry.

ただし、論理的には、イベントを接続できるウィジェットが存在しないため、次の行が機能しなくなります。dijit ID を回復するにはどうすればよいですか?

4

2 に答える 2

1

最善の解決策は、コードが既に使用されている ID でウィジェットを登録しようとしている理由を見つけ、そうしないように変更することです。

@mschrのソリューションは機能するはずですが、他の多くの場所でコードを壊す可能性があり、アプリケーションの奇妙な動作を調査するのに何時間も費やす可能性があるため、再度使用することをお勧めします.

registry.add()とにかく、そのようにして同じ ID のウィジェットを自動的に破棄する場合は、メソッドをオーバーライドしないでください。あなたはそれを行うことができますが、それはあなたがそれを行うべきだという意味ではありません(特にプログラミングでは)。代わりdojo/aspectに、呼び出される前に同じ ID を持つウィジェットを破棄する関数を呼び出しますregistry.add()

require([
    "dojo/aspect",
    "dijit/registry"
], function(
    aspect,
    registry
) {

    aspect.before(registry, "add", function(widget) {           
        if(registry.byId(widget.id)) {
            registry.byId(widget.id).destroy();
            // this warning can save you hours of debugging:
            console.warn("Widget with id==" + widget.id + " was destroyed to register a widget with the same id.");                    
        }
        return [widget];
    });

});

そのオーバーライドなしで @mschr ソリューションを実現する方法に興味があったので、実験用に jsFiddle を作成しました: http://jsfiddle.net/phusick/feXVT/

于 2012-05-18T13:54:29.610 に答える
0

dijit を登録すると、次のようになります。dijit.registry._hash によって参照されます。

function (widget) {
  if (hash[widget.id]) {
    throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered"); 
  }
  hash[widget.id] = widget;
  this.length++;
}

現在、プログラムでウィジェットを配置する contentpane が時々あります (プログラムで、dojo.parser は cpane.unload を処理し、パーサーによってインスタンス化されたウィジェットを derefences / destroy します)。

これが発生した場合、cpane.set('content' foo) または cpane.set('href', bar) を呼び出すときのように、何らかの形式の「アンロード」にフックする必要があります。保持しているウィジェットのインスタンスを破棄して登録解除するには、フックが必要です。そうしないと、プログラムでメモリリークが発生します。

通常、オブジェクトがどこにも参照を持たなくなると、メモリから消去されますが、ウィジェットなどの複雑なオブジェクトでは、「クラス変数」が _outside _widget スコープへの参照を持っていることが多く、ウィジェットを安全に削除できないというフラグが立てられます。ガベージ コレクター...このポイントを取得すると、適切なライフサイクルを実行することがわかりますが、概念が完全に理解される前ではありません..

できることは、dijit.registry を独自のハンドラーでオーバーライドし、ダブレットであるウィジェットを次のように自動的に破棄することです。

// pull in registry in-sync and with global scoped
// accees (aka dijit.registry instead of dj_reg)

require({

     async:false,
     publishRequireResult:true

  }, [

     "dijit.registry"

  ], function(dj_reg) {

   dijit.registry.add = function(widget) {

      // lets change this bit
      if (this._hash[widget.id]) {
          this._hash[widget.id].destroy(); // optinally destroyRecursively
          this.remove(widget.id)
      }
      this._hash[widget.id] = widget;
      this.length++;

   }
});
于 2012-05-18T09:30:18.840 に答える