2013-04-20 17 views
7

Próbuję napisać funkcję, która da mi skompilowany szablon kierownicy (Mam wszystkie moje szablony w osobnych plikach), używając wywołania ajax, aby uzyskać szablon i skompilować go do użycia, ale potrzebuję używać obietnicy, więc mogę jej użyć.ładowanie szablonu kierownicy asynchronicznie

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

Jak mogę to zrobić z obietnicami, więc mogę zrobić coś takiego:

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

prawdopodobnie związane: http://stackoverflow.com/questions/133310/how-can-i-get-jquery-to-perform-a-synchronous- raczej niż asynchroniczny-ajax-re – ubik

+0

@PedroFerreira 'async: false' jest przestarzałe i jest okropnym rozwiązaniem – charlietfl

+0

@charlietfl Tak, zgadzam się. Jednak w niektórych przypadkach może to być interesujące jako opcja. – ubik

Odpowiedz

16

Chovy widzę zaakceptowaniu odpowiedzi, ale może być zainteresowany, aby wiedzieć, że getTemplate może przez łańcuchowym .then() zamiast .success() być napisany prawie jak w pytaniu :

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

lub, przyjmując pomysł charlietfl na przekazywanie danych i powrót obietnica całkowicie złożonego fragmentu:

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

Efekt netto jest identyczna z wersją charlietfl dnia getTemplate ale .then() sprawia, że ​​konieczne tworzenie odroczony wyraźnie. Kod jest zatem bardziej zwarty.

+1

+1 @Beettroot czystsze niż moje rozwiązanie – charlietfl

+0

Dziękuję za przyjęcie Chovy, choć raczej czuję, że ukradłem odrodzenie Charliego: - | –

+0

Nie zapominaj, że ajax jest asynchroniczny i prawdopodobnie powinieneś użyć wywołania zwrotnego w tej funkcji, aby upewnić się, że nie masz problemów. Użyłem tego kodu i miałem dokładnie ten problem – sMyles

4

obserwuję dodaje argument danych do funkcji getTemplate jak również nazwy szablonu.

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

stworzyłem bibliotekę, aby pomóc z tego rodzaju problemu, sprawdź na github

Trzeba tylko dodać do głównej aplikacji widzenia:

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

umieścić to w swoim 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 **/ 
    }); 

i na przykład, aby otworzyć modal z szablonem, który chcesz, musisz tylko:

FactoryController.loadModalTemplate(templateName, callback); 

I nie zapomnij dodać FactoryController i RepositoryController

Powiązane problemy