J'ai un serveur express node.js fonctionnant avec le moteur de modèle Jade.
J'ai un fichier de mise en page jade qui importe le corps des vues individuelles comme suit:
!!!
html
head
title= title || 'Title not set.'
body
#header
h1 Header.
#content!= body //- this renders the body of an individual view
#footer
p Footer.
Par exemple, la page d'index suivante:
p Welcome to the front page.
p This page serves as a now.js test.
Cela fonctionne bien. Cependant, je veux maintenant inclure deux bibliothèques javascript côté client spécifiquement pour cette page d'index (et donc pas très chaque page, c'est pourquoi je ne peux pas le mettre en tête de mise en page).
Cela marche:
//- import jquery
script(type='text/javascript', src='./jquery-1.5.2.min.js');
//- import now.js (hosts itself)
script(type='text/javascript', src='/nowjs/now.js')
//- import the chat client
script(type='text/javascript', src='./indexChatClient.js')
p Welcome to the front page.
p This page serves as a now.js test.
Cependant, cela charge les scripts dans le corps de la page complète, qui n'est pas du HTML valide, non?
Pour autant que je sache, les scripts doivent être chargés dans la tête si je veux le faire correctement, mais la section tête est gérée par le fichier de mise en page.
Alors, comment pourrais-je inclure correctement ces bibliothèques javascript côté client spécifiquement pour une certaine vue/page?
J'ai fait la même chose en utilisant la solution de ce fil:
http://groups.google.com/group/express-js/browse_thread/thread/8c2006dc7bab37b1/f9a273c836e0a2ac
Vous pouvez déclarer une variable "scripts" dans les options d'affichage:
app.js:
app.set('view options', { locals: { scripts: ['jquery.js'] } }); // You can declare the scripts that you will need to render in EVERY page
Que vous pouvez avoir un assistant qui rend les balises de script dans la tête de la mise en page
renderScriptTags () Code d'assistance:
app.helpers({ renderScriptTags: function(scripts) {
return scripts.map(function(script) {
return '<script src="scripts/' + script + '"></script>';
}).join('\n ');
Dans le modèle de mise en page dans la section de tête, vous aurez:
- renderScriptTags(scripts)
Maintenant, pour ajouter un script sur la balise head, il vous suffit de pousser le script dans la variable "scripts" de votre modèle de contenu jade (modèle de corps):
- scripts.Push('myscript.js');
De cette façon, la page affichera jquery.js et myscript.js en tête de la page
[~ # ~] mise à jour [~ # ~]
Il semble que la dernière version express gère les locaux d'une manière différente, pour que cela fonctionne correctement, vous pouvez le faire (je ne suis pas sûr que ce soit la solution optimale, j'aurais besoin de creuser un peu)
Vous pouvez utiliser l'aide renderScriptTags () de la méthode précédente dans votre modèle de mise en page comme précédemment.
Mais ne définissez pas les variables de scripts en locales, créez plutôt une aide dynamique qui rendra une variable scripts disponible dans nos modèles:
app.dynamicHelpers({
scripts: function(req, res){
return ['jquery.js']; //this will be available in all views
}
});
Et puis, pour ajouter un script spécifique, à partir de votre modèle de corps (exactement comme avant):
- scripts.Push('myscript.js');
Maintenant, pour cette vue spécifique, vous devriez avoir correctement rendu jquery.js et myscript.js
Vous pouvez les avoir sur la mise en page et spécifier les bibliothèques à charger sur les "contrôleurs".
// layout.jade
!!!
html
head
title= title || 'Title not set.'
-each script in scripts
script(type='text/javascript', src= script)
body
#header
h1 Header.
#content!= body //- this renders the body of an individual view
#footer
p Footer.
Et votre "contrôleur":
// app.js
app.get('/', function (req, res) {
res.render({
scripts: ['jquery.min.js', '/nowjs/now.js']
}
}
Il est possible de le faire The Right Way (tm) dans le dernier Jade (0.28.1) en le gardant à l'intérieur des modèles/vues, sans pirater le contenu des pages (liens de script) ailleurs:
doctype 5 html tête // bloc nommé nous permet d'ajouter des entrées de tête personnalisées dans chaque page tête de bloc lien title = title (rel = 'stylesheet', href = '/ css/style.css') script (type = "text/javascript", src = "/ js/some- default-script.js ") corps contenu du bloc
étend la disposition // ici nous référençons la tête du modèle et y ajoutons bloc ajoutent la tête meta (nom = "quelque chose", content = "blah") lien (href = "/ css/another.css", rel = "feuille de style", type = "text/css") style div .foo { position: absolue; } script (src = "/ js/page-specific-script.js") bloquer le contenu # page-contents-suit
Voici une autre façon de le faire (en utilisant la réponse de ShadowCloud). En généralisant un peu, vous pouvez spécifier des scripts locaux et distants, puis les reporter jusqu'à après le chargement de la page:
app.js:
app.dynamicHelpers({
scripts: function() {
//scripts to load on every page
return ['js/jquery.min.js','js/jquery-ui.min.js','js/all.js'];
}
});
vous pouvez ensuite ajouter des scripts locaux ou distants à tout moment dans une vue
//- local script
- scripts.Push('js/myPage.js');
//- remote script ( note: this is a schemeless url. You can use http(s)? ones too )
- scripts.Push('//platform.Twitter.com/widgets.js')
layout.jade: (Je le mets à la fin du corps pour charger d'abord les trucs visibles, mais ça peut vraiment aller n'importe où)
//- Bring the scripts into a client-side array,
//- and attach them to the DOM one by one on page load
script
var page_scripts = !{'["' + scripts.join('","') + '"]'};
function loadJS() {
for(var i in page_scripts) {
var e = document.createElement("script");
e.src = page_scripts[i];
document.body.appendChild(e);
}
}
// Check for browser support of event handling capability
if (window.addEventListener)
window.addEventListener("load", loadJS, false);
else if (window.attachEvent)
window.attachEvent("onload", loadJS);
else window.onload = loadJS;
Je suppose que le problème (en lisant brièvement ceci) est que vous ne "videz" pas le tableau, en définissant sa longueur sur 0 pour supprimer les anciennes valeurs, donc chaque demande pourrait simplement pousser de plus en plus de chaînes
Je ne sais pas à quoi servent les approches jusqu'à présent. Pour moi, il est beaucoup plus propre de faire ce qui suit ...
layout.jade:
doctype html
html
head
title= title
block headscripts // placeholder for scripts that need to be in the <head>
link(rel='stylesheet', href='/styles/style.css')
block styles // placeholder for styles
body
block content
script(src='/libs/jquery/dist/jquery.min.js') // this will render before all scripts in every page
block scripts // placeholder for scripts that go in the body
somepage.jade:
extends layout
block styles // this will render in the <head>
link(rel='stylesheet', href='/styles/films.css')
link(rel='stylesheet', href='/styles/pagination.css')
block headscripts // this will also render in the <head>
script(src='/js/somescript.js')
block content
h1= title
div.someotherstuff
block scripts // this will render at the end of the body
script(src='/js/libs/someotherscript.js')
scirpt(src='/libs/doT/doT.js')
De cette façon, peu importe où dans votre .jade
les pages que vous placez vos blocs, elles seront toujours affichées aux bons endroits.