Đây là câu hỏi hơi khó đối với người có kinh nghiệm phát triển web vài năm, nhưng sau khi không tìm thấy câu trả lời trên Ngăn xếp lập trình Stack hoặc Google, tôi đã quyết định hỏi tại đây.Làm cách nào để tách javascript nội tuyến khỏi nội dung được tạo động trong Express/Node.js?
Tôi đang sử dụng tốc khuôn khổ web cho Node.js, nhưng câu hỏi này là không cụ thể cho bất kỳ khuôn khổ web hoặc ngôn ngữ lập trình.
Dưới đây là danh sách các trò chơi được truy vấn từ cơ sở dữ liệu. Mỗi thực thể trò chơi là một dòng của bảng duy nhất, được tạo ra bằng cách sử dụng cho vòng:
table.table
tbody
for game in games
tr
td.span2
img.img-polaroid(src='/img/games/#{game.largeImage}')
// continues further
Mỗi Đánh giá khối, cũng như mỗi Mua nút/hộp thoại modal được tạo ra bởi for-loop với id phù hợp với trò chơi. Ví dụ: nút Mua cho tín ngưỡng của Assassin sẽ có id = "price-assassins-creed". # {variable} - là cách bạn tham chiếu biến trong Jade, được truyền từ máy chủ.
button.btn.btn-primary.btn-mini(id='price-#{game.slug}', href='#buyModal', role='button', data-toggle='modal')
và
.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
và
script(type='text/javascript')
$('#_#{game.slug}').raty({
path: '/img',
round : { down: .25, full: .6, up: .76 },
score: #{game.rating}/#{game.votes},
readOnly: true
});
Multiply rằng bằng số lượng trò chơi và đó là bao nhiêu kịch bản inline Tôi có trên một trang.
chưaTệ hơn nữa, tôi phải giải thích cho các trường hợp sau:
- tài khoản không đăng nhập: hiển thị ở trên kịch bản giá trong chế độ read-only.
- của người sử dụng đăng nhập, nhưng vẫn chưa bình chọn chưa:
... trong trường hợp đó, sử dụng kịch bản sau đây:
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);
}
});
}
});
- của người sử dụng đăng nhập nhưng bị tạm ngưng xếp hạng: Sao chép và dán một tập lệnh chỉ đọc khác cho điều kiện cụ thể này là nếu-else.
câu chuyện dài ngắn, nó đã trở thành một cơn ác mộng bảo trì cố gắng để duy trì hoạt Javascript tất cả điều này trong .jade mẫu tác phẩm của tôi, và đánh dấu của tôi trông không thể chấp nhận bẩn.
Giải pháp cho việc này là gì? Điều này có vẻ giống như một kịch bản phổ biến cho các ứng dụng CRUD. Lý tưởng nhất là tôi muốn chuyển tất cả javascript sang một số riêng biệt .js tệp. Nhưng nếu tôi có thể loại bỏ một số mã trùng lặp, đó sẽ là tuyệt vời quá.
Vấn đề là nếu tôi di chuyển javascript nội tuyến sang một tệp riêng biệt làm cách nào để biết tôi đang xếp hạng trò chơi nào? Làm cách nào để biết nút Mua có người dùng đã nhấp vào?
Ngay bây giờ không có sự mơ hồ bởi vì đối với N trò chơi tôi đã mua N nút, N hộp thoại modal và N kịch bản đánh giá. Bất kể những gì ai nghĩ về phong cách lập trình này, đó là một cách khủng khiếp để duy trì mã.
Vui lòng chia sẻ một số thông tin chi tiết với một noobie!
Cảm ơn bạn trước.
Dưới đây là một đoạn mã hoàn chỉnh các tập tin games.jade tôi:
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!');
});
});
Tường thành văn bản lớn nhưng là một câu hỏi hay. +1 – Ben