2013-04-20 12 views
7

Sto provando a scrivere una funzione che mi fornirà un modello manubrio compilato (ho tutti i miei modelli in file separati) utilizzando una chiamata ajax per ottenere il modello e compilarlo per l'uso, ma ho bisogno usare una promessa così posso effettivamente usarla.caricamento manubrio modello in modo asincrono

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

Come posso fare questo con promesse in modo da poter fare qualcosa di simile:

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

possibilmente correlate: http://stackoverflow.com/questions/133310/how-can-i-get-jquery-to-perform-a-synchronous- piuttosto che asincrono-ajax-re – ubik

+0

@PedroFerreira 'async: false' è deprecato ed è una soluzione terribile – charlietfl

+0

@charlietfl Sì, sono d'accordo. Ma potrebbe comunque essere interessante come opzione, in casi particolari. – ubik

risposta

16

Chovy, vedo che avete accettato una risposta, ma si potrebbe essere interessati a sapere che getTemplate può, concatenando .then() piuttosto che .success(), essere scritto quasi come nella questione :

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

oppure, adottando l'idea di charlietfl per passare i dati e restituire una promessa di un frammento completamente composta:

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

L'effetto nett è identico alla versione di charlietfl di getTemplate ma .then() rende necessario creare una differita in modo esplicito. Il codice è quindi più compatto.

+1

+1 @Beettroot più pulito della mia soluzione – charlietfl

+0

Grazie per l'accettazione di Chovy, anche se preferisco sentire che ho rubato il respingimento Charlie Sorry –

+0

Non dimenticare che ajax è asincrono e probabilmente dovresti usare una funzione di callback in quella funzione per assicurarti di non avere problemi. Utilizzato questo codice e ha avuto questo problema esatto – sMyles

4

seguito aggiunge un argomento di dati alla funzione getTemplate così come il nome del modello.

$(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

ho creato una biblioteca per aiutare con questo tipo di problema, controllare in github

Basta aggiungere questo alla tua principale vista di app:

<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> 

messo questo nella vostra 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 **/ 
    }); 

e loro, ad esempio, per aprire un modale con il modello che si desidera, è sufficiente:

FactoryController.loadModalTemplate(templateName, callback); 

E non dimenticate di aggiungere il FactoryController e RepositoryController

Problemi correlati