2013-04-20 61 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 2013-04-20 10:56:41

+0

@PedroFerreira'async:false'已被棄用,是一個可怕的解決方案 – charlietfl 2013-04-20 11:01:29

+0

@charlietfl是的,我同意。但在特定情況下,作爲一種選擇,它可能仍然很有趣。 – ubik 2013-04-20 11:04:40

回答

16

Chovy,我看你已經接受一個答案,但你可能有興趣知道,getTemplate可以通過鏈接.then()而不是.success(),寫成幾乎一樣的問題:

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); 
    }); 
} 

實價的效果是相同的charlietfl的版本getTemplate.then()使得沒有必要建立一個明確的推遲。代碼因此更緊湊。

+1

+1 @Beettroot比我的解決方案更清潔 – charlietfl 2013-04-21 23:48:20

+0

謝謝你接受Chovy,雖然我寧願覺得我偷走了查理的代理權: - | – 2013-04-22 08:48:37

+0

不要忘記,ajax是異步的,你應該使用該函數的回調來確保你沒有問題。使用此代碼,並有這個確切的問題 – sMyles 2014-04-17 03:08:43

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