2013-05-06 10 views
5

W mojej aplikacji potrzebuję API (coś takiego jak Google Maps javascript API), za pomocą którego mogę wysłać niestandardowy javascript (z pewnymi informacjami związanymi z sesją i żądaniami)) jako odpowiedź. Javascript jest następnie używany do wykreślania niektórych wykresów w interfejsie użytkownika. Używam Express with Jade jako mojego silnika szablonowego. Kod, który obecnie używam jest:Express/Node.js: Renderuj niestandardowy javascript jako odpowiedź

app.use('/graph',function(req, res){ 
    //send out graph data 
    var var_name = req.session.var_name //fetch something from session 
    var graphData = fetchGraphData(req.query.graph); //function that fetches graph data 
    res.contentType("text/javascript"); 
    res.render(__dirname + '/views/graph.jade', { 
    title: "Title", queryStr: JSON.stringify({var_name: var_name, graphData: graphData }) 
    }); 
}); 

a plik jade:

| some_var_name = { 
|  initGraph : function(divId){ 
|  //some code here 
|  var graphData = !{graphData} 
|  // do something        

Jako obejście, zacząłem każdy wiersz pliku jade z |, tak że jade analizuje tekst jako zwykły tekst i nie dodaje żadnych znaczników html! Działa dobrze, ale czy istnieje lepszy sposób na zrobienie tego? Rozwiązanie może lub nie może używać Jade!

+0

Nie wiem, ile szablonu jest rzeczywiście wymagane, ale nadal możesz użyć 'res.send', aby wysłać dowolny ciąg znaków. – TheHippo

+0

@TheHippo: Dzięki za odpowiedź! Ale chciałbym uporządkować dane odpowiedzi w plikach, ponieważ byłoby sporo takich działań, a plik też jest dość długi! –

Odpowiedz

6

Powinieneś zajrzeć do underscore templates. Myślę, że generowanie arbitralnego tekstu byłoby nieco czystsze. Jade jest specjalnie zaprojektowana do renderowania HTML.

Możesz także wypróbować Mustache lub Handlebars.

Na podstawie Twojego komentarza widzę, że chcesz nadal używać res.render do renderowania szablonu. consolodate.js dodaje obsługę wszystkich głównych silników szablonów do Express. W tym szablony podkreślenia, kierownice, wąsy i kurz, wspomniane przez @ TheHippo.

+0

Również [kurz] (http://akdubya.github.io/dustjs/#dust) powinien działać dobrze, ponieważ jest agnostyczny. (Nie tylko szablon HTML) – TheHippo

+0

Dzięki za twoje dane wejściowe. Poszedłem z kierownicą. Wyglądaj teraz znacznie czystsze! –

1

Możesz spróbować zdefiniować funkcje JavaScript, które chcesz wysłać do przeglądarki w oddzielnym module, poza szablonem, co jest prawdopodobnie poprawniejszym sposobem z punktu widzenia "dotyczy separacji". Również funkcje zdefiniowane w oddzielnym module mogą być używane zarówno na serwerze, jak i w przeglądarce.

Następnie możesz przekonwertować funkcje na łańcuchy, używając metody toString() w funkcji, która wywołuje szablon lub bezpośrednio wewnątrz szablonu, jeśli obsługuje zwykły JavaScript, co ma miejsce w przypadku podkreśleń, szablonów EJS i doT (I próbowałem zarówno podkreślenia i EJS i skończyło się kropka, która jest nie tylko najszybszym, ale bardzo wszechstronny - to sprawdzić): kod

JS:

// if you send the same functions you may want to convert them to strings in advance 
var data = { 
    funcStr: func.toString(); 
}; 
res.render(view, data); 

szablonu (DOT):

<script type="text/javascript"> 
    func = {{= it.funcStr }}; 

    // now you can call it here if you want but I would use 
    // separate JavaScript files 
    func(); 
</script> 

Używam go do wysyłania gotowych szablonów do przeglądarki razem ze stroną na pierwszym załadowaniu strony, ale myślę, że można z niej korzystać również w twoim przypadku.

Jako pytanie uboczne, dlaczego nie można po prostu połączyć wszystkich tych funkcji w osobnym module JavaScript i załadować je jako zwykły plik skryptowy?

+0

Interfejs API, który eksponuję, po prostu zwraca plik javascript po pewnym podstawowym uwierzytelnieniu HTTP, a odpowiedź js zawiera pewne informacje o auth i niektóre parametry żądania do interakcji z socket.io. Odpowiedź js jest podobna do interfejsu Google Maps API.Odpowiedź może być tylko plikiem 1 js, więc nie mogę połączyć funkcji w osobnym pliku, chyba że wszystkie oddzielne pliki zostaną skompilowane w jeden przed renderowaniem odpowiedzi! –

Powiązane problemy