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