2012-04-27 11 views
0

クライアントサイドのJSアプリケーションで、各アイテムを表示するためのテンプレートを読み込む必要があります。ノートであるとしましょう。非同期テンプレートの読み込み - 一度ロードするにはどうすればいいですか?

問題は非同期部分です。テンプレートを一度だけロードできるようにすることはできません。ノートがrender機能を呼び出すたびにロードされます。ここで

はいくつかのコードです:

var notes = [ {}, {}, {} ] // Some Note objects 
notes.forEach(function(note) { 
    render(note) 
} 

// Have some variable to hold the template 
var template 

// Now on the render function 
function render(note) { 

    // First, if the template exists, go straight to the next function 
    if (template) { 

     // The display function takes care of appending the note 
     // to the body after applying datas on the template 
     display(note) 
    } 
    else { 
     // loadTemplate just loads the template in an ajax request 
     // and executes the callback with the template as argument 
     loadTemplate(function(data) { 

      // I fill in the template variable 
      template = data 

      // And I display the note since the template is available 
      display(note) 
     }) 
    } 
} 

したがって、この場合には、それは、これを防ぐために、チェックがあるにもかかわらず、3回のテンプレートをロードします。私はこれが3つのテンプレートが他の人にまっすぐに行くためだと思いますが、どうすればこれを防ぐことができますか?

これはブラウザをフリーズするので、私は同期ajaxの読み込みを使いたくありません。

を編集してください。最後に、少し修正した@ Managuのソリューションを使用しました。

代わりに彼のループを使用しての、私は次のように使用してきた、はるかにエレガント:

while (backlog.length) { 
    display(backlog.shift()) 
} 
+0

'.lodaTemplate'は読み込むテンプレートをどのように知っていますか? – Esailija

+0

このアプリケーションでは、今のところロードするテンプレートは1つだけです。 –

答えて

1

おそらく、テンプレートがロードされた後に行われる必要がある作業のバックログを保ちますか?基本的に、非同期によって引き起こされるインピーダンスの不一致を滑らかにするキュー。

var template; 
var backlog; 

function render(note) 
{ 
    if (template) { 
     // Template already loaded, just display. 
     display(note); 
    } else if (backlog) { 
     // Template being loaded, push work onto backlog. 
     backlog.push(note); 
    } else { 
     // Template not being loaded yet. Create backlog queue and launch request 
     // to load template. 
     backlog=[note]; 
     loadTemplate(function(loaded_template) { 
      // Template finally came over the wire. Save it, and then 
      // work off the backlog. 
      template = loaded_template; 
      for (var note=backlog.shift(); 
       backlog.length!=0; 
       note=backlog.shift()) 
      { 
       display(note); 
      } 
     }); 
    } 
} 
+0

これにより、テンプレートが複数回読み込まれるという事実は変わりません。 2番目のノートが関数に来ると、 'template'はまだ空ですので、テンプレートを取得する別のリクエストを行います。 –

+0

@FlorianMargaine。うん、あなたは正しい。これを修正しました。 – Managu

+0

ああ、いいです!私はそれを試してみてください:)非常にエレガントでないtho :( –

2
var loadTemplate = function() { 
    var promise = $.get("/"); 

    loadTemplate = function() { 
     return promise; 
    }; 

    return promise; 
}; 

jQueryのは、ここで必要とされていない、私はちょうど擬似コードとして記述していることに注意してください。遅延を提供するライブラリを使用できます。

loadTemplate().then(function(data) { 

    // I fill in the template variable 
    template = data 

    // And I display the note since the template is available 
    display(note) 
}) 
+0

非常にエレガント:) –

0

「同期ajaxの読み込みは、ブラウザをフリーズするので使用しません。」

同期ajaxはjQueryを使用しようとするとブラウザをフリーズします。 Frame.jsは、あなたが抱っているように問題を解決するように設計されています。 Frameでこの問題を解決するには複数の方法がありますが、すべてにはある程度の同期と非同期のミックスが必要です。おそらく最も簡単な方法は、次のようになります。

Frame(function(next){ 
    loadTemplate(next); 
}); 
Frame(function(next, data){ // data here is the value passed to loadTemplate's callback 
    notes.forEach(function(note) { 
     template = data; 
     display(note); 
    }); 
    next(); 
}); 

テンプレートが何であるかわからない、それは各ノートに同じまたは異なる場合があります場合は、あなたの代わりにこれを行う可能性があります:

notes.forEach(function(note) { 
    Frame(function(next){ 
     loadTemplate(note.templateName, next); // next here is a callback to advance to the next Frame 
    }); 
    Frame(function(next, template){ 
     display(note, template); 
     next(); 
    }); 
}); 

ことテンプレートは同期して読み込まれますが、ディスプレイは非同期に更新されます。

+0

Frame.jsはまったく別の遅延ライブラリです:)。これは質問に答えますが、@エシリアはすでにこれを提案しています。あなたの努力をありがとうtho! –

関連する問題