私はapache、php、js/jqueryに基づいたWebアプリケーションを持っています。ドキュメントがロードされると、アプリケーションの1つのモジュールが初期化されます。このシーケンスは、いくつかのタスクを実行するinit()関数を呼び出します。特に、ajaxを介して2つのhtmlダイアログをフェッチし、それらを既存のページに挿入します。これらのダイアログへの参照は変数として保存されるため、スクリプト全体でjqueryセレクターを指定する必要はありませんが、代わりにこれらの変数を使用できます。フェッチされたダイアログ内の要素にハンドラーをバインドしようとしたときに変数が「未定義」である場合がほとんどないことを除いて、これは正常に機能します。それとは別に、ダイアログはアプリケーション全体で使用できるため、これは奇妙なことです。これは、ajax呼び出しが成功したことを示していますが、明らかに何らかの競合状態があります。バインドの試行後。
私の理解では、バインドはwhen()の.done()部分で行われ、ダイアログのajax取得がwhen()内で終了した後にのみ実行されるため、これは発生しないはずです。
どうやら私はここで基本的な何かが欠けています。誰かが私にヒントを得ましたか?
以下は、実際の実装からのコードの抜粋を引用しています。一部の部分として構文的に無効に見える場合がありますが、これは、ここでは関係のないコード部分が削除されたためです。短縮されていないコードは正常に機能します。
変数:
Shorty.Tracking.Dialog.List:{};
Shorty.Tracking.Dialog.Click:{};
初期化シーケンス:
$(window).load(function(){
//...
var dfd = new $.Deferred();
$.when(
// load layout of dialog to show the list of tracked clicks
Shorty.Tracking.init()
).done(function(){
// bind actions to basic buttons
Shorty.Tracking.Dialog.List.find('#close').on('click',function(){
// ...
});
// ...
});
// ...
})
短縮されたinit関数:
Shorty.Tracking.init:function(){
// ...
var dfd=new $.Deferred();
// two dialogs are used by this plugin
var dialogs={
'list': Shorty.Tracking.Dialog.List,
'click': Shorty.Tracking.Dialog.Click
};
// load dialogs from server
$.each(['list','click'],function(i,dialog){
if (...){
// ...
dfd.resolve();
}else{
// load dialog layout via ajax and create a freshly populated dialog
$.ajax({
type: 'GET',
url: OC.filePath('shorty-tracking','ajax','layout.php'),
data: { dialog: dialog},
cache: false,
dataType: 'json'
}).pipe(
function(response){return Shorty.Ajax.eval(response)},
function(response){return Shorty.Ajax.fail(response)}
).done(function(response){
// create a fresh dialog
// insert it alongside the existing dialogs in the top controls bar
$('#controls').append(response.layout);
switch (dialog){
case 'list':
Shorty.Tracking.Dialog.List=$('#controls #shorty-tracking-list-dialog').first();
break;
case 'click':
Shorty.Tracking.Dialog.Click=$('#controls #shorty-tracking-click-dialog').first();
} // switch
dfd.resolve();
}).fail(dfd.reject)
} // else
}); // each
return dfd.promise();
},
ベルギの答えで、私はどうやら元の問題を取り除くことができました。これまで、失敗したバインドの試行を検出できませんでした。しかし、私はその提案に完全に従うことはできませんでした。彼の答えでは、直接割り当てを優先して、初期化メソッドのswitchステートメントを削除することを提案しました。これは確かにはるかにエレガントですが、それは機能しません。javascriptが変数に格納されている参照や関数をどのように処理するかについて、私の側には誤解がある印象があります。
たぶん、あなた、ベルギ、または他の誰かがこれについて説明する光を当てることができます:
これは、上から変更された初期化方法です。
init:function(){
if (Shorty.Debug) Shorty.Debug.log("initializing tracking list");
// check if dialogs already exist
if ( $.isEmptyObject(Shorty.Tracking.Dialog.List)
&& $.isEmptyObject(Shorty.Tracking.Dialog.Click) ){
// two dialogs are used by this plugin
var dialogs={
'list': Shorty.Tracking.Dialog.List,
'click': Shorty.Tracking.Dialog.Click
};
// load dialogs from server
var dfds=$.map(dialogs,function(obj,dialog){
// load dialog layout via ajax and append it to the collection of dialogs in the controls
return $.ajax({
type: 'GET',
url: OC.filePath('shorty-tracking','ajax','layout.php'),
data: { dialog: dialog},
cache: false,
dataType: 'json'
}).pipe(
function(response){return Shorty.Ajax.eval(response)},
function(response){return Shorty.Ajax.fail(response)}
).done(function(response){
// create a fresh dialog and insert it alongside the existing dialogs in the top controls bar
$('#controls').append(response.layout);
// obj=$('#controls #shorty-tracking-'+dialog+'-dialog').first();
switch(dialog){
case 'list':
Shorty.Tracking.Dialog.List=$('#controls #shorty-tracking-list-dialog').first();
break;
case 'click':
Shorty.Tracking.Dialog.Click=$('#controls #shorty-tracking-click-dialog').first();
break;
} // switch
})
}) // map
return $.when.apply(null, dfds);
}else{
// dialogs already loaded, just clean them for usage
Shorty.Tracking.Dialog.List.find('#list-of-clicks tbody tr').remove();
new Deferred().resolve();
} // else
},
真ん中には、割り当てステートメントがコメントアウトされており、現在、以下のswitchステートメントに置き換えられています。obj.elementなどのいくつかのバリエーションを試しましたが、失敗しました。関数の外では、変数Shorty.Tracking.Dialog.ListおよびShorty.Tracking.-Dialog.Clickは空のままです。
私はWebスタッフとjs/jqueryの完全な初心者です。しかし、私は確かに、参照を処理するこの方法についてもっと知りたいと思っています。