Questo è un po 'noob-domanda per qualcuno che ha avuto un paio di anni di esperienza di sviluppo web, ma dopo non trovando la risposta su entrambi i programmatore Pila Cambio o Google, ho deciso di chiedere qui.Come separare javascript in linea da contenuti generati dinamicamente in Express/Node.js?
Sto usando espresso quadro web per Node.js, ma questa domanda non è specifico per ogni framework web o di linguaggio di programmazione.
Ecco un elenco di giochi che vengono interrogati dal database. Ogni entità gioco è una singola riga della tabella, generato utilizzando un ciclo for:
table.table
tbody
for game in games
tr
td.span2
img.img-polaroid(src='/img/games/#{game.largeImage}')
// continues further
Ogni Valutazione blocco, così come ogni finestra Acquisto tasto/modal sono generati da il ciclo for con un ID che corrisponde al gioco. Ad esempio, il pulsante Acquista per Assassin's Creed avrà id = "price-assassins-creed". # {variable} - è il modo in cui si fa riferimento a una variabile in Jade, passata dal server.
button.btn.btn-primary.btn-mini(id='price-#{game.slug}', href='#buyModal', role='button', data-toggle='modal')
e
.modal.hide.fade(id='modal-#{game.slug}', tabindex='-1', role='dialog', aria-labelledby='myModalLabel', aria-hidden='true')
.modal-header
span.lead Game Checkout
img.pull-right(src='/img/new_visa_medium.gif')
.modal-body
label
i.icon-user
| Name on Card
input.input-medium(type='text')
label
i.icon-barcode
| Card Number
input.input-medium(type='text', placeholder='•••• •••• •••• ••••', maxlength=16)
label
i.icon-time
| Expiration Date
input.input-mini(type='text', placeholder='MMYY', maxlength=4)
label
i.icon-qrcode
| Card Code
input.input-mini(type='text', placeholder='CVC', maxlength=4)
.modal-footer
button.btn(data-dismiss='modal', aria-hidden='true') Cancel
button.btn.btn-primary(id='#{game.slug}') Buy
e
script(type='text/javascript')
$('#_#{game.slug}').raty({
path: '/img',
round : { down: .25, full: .6, up: .76 },
score: #{game.rating}/#{game.votes},
readOnly: true
});
moltiplicare per il numero di giochi e questo è il numero di script in linea che ho su una sola pagina.
ancora peggio, devo rendere conto dei seguenti casi:
- utente non è loggato: display sopra scritto rating in modalità di sola lettura.
- utente connesso in, ma non ha ancora votato:
... in questo caso, utilizzare il seguente script:
script(type='text/javascript')
$('#_#{game.slug}').raty({
path: '/img',
round : { down: .25, full: .6, up: .76 },
score: #{game.rating}/#{game.votes},
readOnly: false,
click: function (score, event) {
var self = this;
$.meow({
message: 'Thanks for voting. Your rating has been recorded.',
icon: 'http://png-3.findicons.com/files/icons/1577/danish_royalty_free/32/smiley.png'
});
$.ajax({
type: 'POST',
url: '/games/rating',
data: {
slug: $(self).attr('id').slice(1),
rating: score
},
success: function() {
console.log('setting to read-only');
$(self).raty('readOnly', true);
}
});
}
});
- utente autenticato ma sospeso dalla classificazione: copia e incolla ancora un altro script di sola lettura per questa particolare condizione if-else.
Per farla breve, è diventato un incubo di manutenzione cercando di mantenere tutto questo JavaScript nei miei .jade file di modello, e il mio margine di profitto sembra inaccettabilmente sporco.
Qual è una soluzione per questo? Questo sembra uno scenario così comune per le applicazioni CRUD. Idealmente, mi piacerebbe spostare tutto il javascript in un separato .js file. Ma se potessi rimuovere del codice duplicato, sarebbe fantastico.
Il problema è se si sposta in linea javascript in un file separato come faccio a sapere qual è il gioco? Come faccio a sapere su quale pulsante Acquista è stato fatto clic su utente?
In questo momento non c'è ambiguità perché per N giochi che ho N comprare pulsanti, N finestre di dialogo modali e N script di rating. Indipendentemente da ciò che qualcuno pensa di questo stile di programmazione, è un modo terribile per mantenere il codice.
Si prega di condividere qualche intuizione con un noobie!
Grazie in anticipo.
Ecco un frammento di codice completo del mio file games.jade:
extends layout
block content
br
ul.nav.nav-pills
if heading === 'Top 25'
li.active
a(href='/games') Top 25
else
li
a(href='/games') Top 25
if heading === 'Action'
li.active
a(href='/games/genre/action') Action
else
li
a(href='/games/genre/action') Action
if heading === 'Adventure'
li.active
a(href='/games/genre/adventure') Adventure
else
li
a(href='/games/genre/adventure') Adventure
if heading === 'Driving'
li.active
a(href='/games/genre/driving') Driving
else
li
a(href='/games/genre/driving') Driving
if heading === 'Puzzle'
li.active
a(href='/games/genre/puzzle') Puzzle
else
li
a(href='/games/genre/puzzle') Puzzle
if heading === 'Role-Playing'
li.active
a(href='/games/genre/role-playing') Role-Playing
else
li
a(href='/games/genre/role-playing') Role-Playing
if heading === 'Simulation'
li.active
a(href='/games/genre/simulation') Simulation
else
li
a(href='/games/genre/simulation') Simulation
if heading === 'Strategy'
li.active
a(href='/games/genre/strategy') Strategy
else
li
a(href='/games/genre/strategy') Strategy
if heading === 'Sports'
li.active
a(href='/games/genre/sports') Sports
else
li
a(href='/games/genre/sports') Sports
if games.length == 0
.alert.alert-warning
| Database query returned no results.
else
table.table
tbody
for game in games
.modal.hide.fade(id='modal-#{game.slug}', tabindex='-1', role='dialog', aria-labelledby='myModalLabel', aria-hidden='true')
.modal-header
span.lead Game Checkout
img.pull-right(src='/img/new_visa_medium.gif')
.modal-body
label
i.icon-user
| Name on Card
input.input-medium(type='text')
label
i.icon-barcode
| Card Number
input.input-medium(type='text', placeholder='•••• •••• •••• ••••', maxlength=16)
label
i.icon-time
| Expiration Date
input.input-mini(type='text', placeholder='MMYY', maxlength=4)
label
i.icon-qrcode
| Card Code
input.input-mini(type='text', placeholder='CVC', maxlength=4)
.modal-footer
button.btn(data-dismiss='modal', aria-hidden='true') Cancel
button.btn.btn-primary(id='#{game.slug}') Buy
tr
td.span2
img.img-polaroid(src='/img/games/#{game.largeImage}')
td
a(href='/games/#{game.slug}')
strong
= game.title
|
if user.userName
button.btn.btn-primary.btn-mini(id='price-#{game.slug}', href='#modal-#{game.slug}', role='button', data-toggle='modal')
i.icon-shopping-cart.icon-white
= game.price
if user.purchasedGames && user.purchasedGames.length > 0
for mygame in user.purchasedGames
if mygame.game.slug == game.slug
script(type='text/javascript')
$('#price-#{game.slug}').removeAttr('href');
$('#price-#{game.slug}').html('<i class="icon-shopping-cart icon-white"></i> Purchased');
div
span(id='_' + game.slug)
span(id='votes', name='votes')
| (#{game.votes} votes)
div
small.muted
div #{game.releaseDate} | #{game.publisher}
div #{game.genre}
p
=game.description
// logged-in users
if user.userName
if game.votedPeople.length > 0
for voter in game.votedPeople
if voter == user.userName || user.suspendedRating
script(type='text/javascript')
$('#_#{game.slug}').raty({
path: '/img',
round : { down: .25, full: .6, up: .76 },
score: #{game.rating}/#{game.votes},
readOnly: true
});
else
script(type='text/javascript')
$('#_#{game.slug}').raty({
path: '/img',
round : { down: .25, full: .6, up: .76 },
score: #{game.rating}/#{game.votes},
readOnly: false,
click: function (score, event) {
var self = this;
$.meow({
message: 'Thanks for voting. Your rating has been recorded.',
icon: 'http://png-3.findicons.com/files/icons/1577/danish_royalty_free/32/smiley.png'
});
$.ajax({
type: 'POST',
url: '/games/rating',
data: {
slug: $(self).attr('id').slice(1),
rating: score
},
success: function() {
console.log('setting to read-only');
$(self).raty('readOnly', true);
}
});
}
});
else
if (user.suspendedRating)
script(type='text/javascript')
$('#_#{game.slug}').raty({
path: '/img',
round : { down: .25, full: .6, up: .76 },
score: #{game.rating}/#{game.votes},
readOnly: true
});
else
script(type='text/javascript')
$('#_#{game.slug}').raty({
path: '/img/',
round : { down: .25, full: .6, up: .76 },
score: #{game.rating}/#{game.votes},
readOnly: false,
click: function (score, event) {
var self = this;
$.meow({
message: 'Thanks for voting. Your rating has been recorded.',
icon: 'http://png-3.findicons.com/files/icons/1577/danish_royalty_free/32/smiley.png'
});
$.ajax({
type: 'POST',
url: '/games/rating',
data: {
slug: $(self).attr('id').slice(1),
rating: score
},
success: function() {
console.log('setting to read-only');
$(self).raty('readOnly', true);
}
});
}
});
else
script(type='text/javascript')
$('#_#{game.slug}').raty({
path: '/img',
round : { down: .25, full: .6, up: .76 },
score: #{game.rating}/#{game.votes},
readOnly: true
});
script(type='text/javascript')
$('##{game.slug}').click(function() {
var game = this;
$.ajax({
type: 'post',
url: '/buy',
data: {
slug: $(game).attr('id')
}
}).success(function() {
$('#price-#{game.slug}').attr('disabled', 'true');
$('#modal-' + $(game).attr('id')).modal('hide');
humane.log('Your order has been submitted!');
});
});
Grande muro di testo ma una domanda piuttosto buona +1 – Ben