2013-04-20 8 views
7

テンプレートを取得してコンパイルするためのコンパイル済みのハンドルバーテンプレート(別ファイルにすべてのテンプレートがあります)をAjax呼び出しを使って作成しようとしていますが、私は実際にそれを使用することができる約束を使用する。ハンドルバーのテンプレートを非同期にロードする

function getTemplate(name){ 
    $.get('/'+name+'.hbs').success(function(src){ 
     var template = Handlebars.compile(src); 
     //can't return the template here. 
    }); 
} 

私はのような何かを行うことができますので、私は約束でこれをどのように行うのです。続き

$("a").click(function(e){ 
    getTemplate('form').done(function(template){ 
     $("body").append(template({ 
       name: "My Name" 
      }) 
     ); 
    }); 
}); 
+0

を追加するのを忘れ:http://stackoverflow.com/questions/133310/how-can-i-get-jquery-to-perform-a-synchronous-非同期-Ajax-re – ubik

+0

@PedroFerreira 'async:false'は非難され、ひどい解決策です。 – charlietfl

+0

@charlietflはい、私は同意します。しかし、それはまだ特別な場合にはオプションとして面白いかもしれません。 – ubik

答えて

16

Chovyは、私はあなたが答えを受け入れてきたが、あなたはgetTemplateは、.success()ではなく.then()を連鎖によって、ほとんどの問題のように書くことができることを知って興味があるかもしれません見ます:

function getTemplate(name) { 
    return $.get('/'+name+'.hbs').then(function(src) { 
     return Handlebars.compile(src); 
    }); 
} 

または、データを渡すcharlietflのアイデアを採用してください。完全に合成されたフラグメントの約束を返す:

function getTemplate(name, data) { 
    return $.get('/'+name+'.hbs').then(function(src) { 
     return Handlebars.compile(src)(data); 
    }); 
} 

正味の効果はgetTemplateのcharlietflのバージョンと同じですが、.then()は、明示的に繰延を作成する必要がなくなります。したがって、コードはよりコンパクトです。私はこの種の問題を支援するためのライブラリを作成し

+1

+1私の解決策よりも@Beettrootクリーナー – charlietfl

+0

Chovyを受け入れていただきありがとうございます。私はチャーリーの代理人を盗んだと感じています。 –

+0

ajaxが非同期であることを忘れないでください。問題がないことを確認するために、おそらくその関数でコールバックを使用する必要があります。このコードを使用し、この正確な問題を抱えていた – sMyles

4

getTemplate関数にデータ引数だけでなく、テンプレート名を追加します。

$(function(){ 
    var postData={title: "My New Post", content: "This is my first post!"}; 
getTemplate('template-1',postData).done(function(data){ 
    $('body').append(data) 
}) 
}); 

function getTemplate(name,data){ 
    var d=$.Deferred(); 

    $.get(name+'.html',function(response){ 

    var template = Handlebars.compile(response); 
    d.resolve(template(data)) 
    }); 

    return d.promise(); 

} 

DEMO

1

github

でチェックあなただけのメインアプリビューにこれを追加する必要があります。

<script type="text/x-handlebars" data-template-name="application"> 
    <!-- Your HTML code --> 
    <div class="container"> 
     <div class="modal fade" id="editView" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> 
      <div class="modal-dialog"> 
       <div class="modal-content"> 
        {{view MainApp.ModalContainerView elementId="modalContainerView"}} 
       </div><!-- /.modal-content --> 
      </div><!-- /.modal-dialog --> 
     </div><!-- modal edit dialog --> 
     {{view MainApp.AppContainerView elementId="appContainerView"}} 
     {{outlet}} 
    </div> <!-- main container --> 
</script> 

あなたMainAppに

にこれを入れます
var MainApp = Em.Application.create({ 
    LOG_TRANSITIONS: true, 
    ready: function() { 
    /** your code **/ 
    MainApp.AppContainerView = Em.ContainerView.extend({}); 
    MainApp.ModalContainerView = Em.ContainerView.extend({}); 
    /** And other containerView if you need for sections in tabs **/ 
    }); 

などのテンプレートを使用して、必要なテンプレートを使用してモーダルを開くには、次のようにします。

FactoryController.loadModalTemplate(templateName, callback); 

ではなく、おそらく関連FactoryControllerとRepositoryController

関連する問題