2012-11-27 8 views
6

Birkaç yıl süren web geliştirme deneyimine sahip birisi için bir soru sözkonusu değil, fakat cevabı bulamadıktan sonra Programmer Yığın Değişimi veya Google burada sormaya karar verdim.Satır içi javascript, Express/Node.js'de dinamik olarak oluşturulan içerikten nasıl ayrılır?

Ben node.js için Ekspres web çerçevesi kullanıyorum, ancak bu soru, herhangi bir web çerçevesi veya programlama diline özgü değildir.

Veritabanından sorgulanan oyunların listesi.

table.table 
     tbody 
     for game in games 
      tr 
      td.span2 
       img.img-polaroid(src='/img/games/#{game.largeImage}') 
       // continues further 

enter image description here

Her Puanlama blok yanı sıra her Satın düğmesi/kalıcı iletişim tarafından oluşturulmaktadır: Her oyun varlık bir için-döngü kullanılarak oluşturulan tek tablo satırı vardır Oyunla eşleşen bir kimlik için for döngüsü. Örneğin, Assassin's Creed için Buy düğmesi id = "price-assassins-creed" olacaktır. # {variable} - Sunucudan aktarılan Jade'deki bir değişkeni nasıl referans gösterdiğinizdir.

button.btn.btn-primary.btn-mini(id='price-#{game.slug}', href='#buyModal', role='button', data-toggle='modal') 

ve

.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 

ve
script(type='text/javascript') 
    $('#_#{game.slug}').raty({ 
    path: '/img', 
    round : { down: .25, full: .6, up: .76 }, 
    score: #{game.rating}/#{game.votes}, 
    readOnly: true 
    }); 

Çarp o oyunların sayısına göre ve ben bir sayfada kaç satır içi komut var. Henüz

Daha da kötüsü, ben şu durumlarda hesabını vermek zorunda:

  • Kullanıcı giriş yapmış değil: Salt okunur modda değerlendirme komut yukarıdaki ekran.
  • Kullanım giriş yapmış, ancak henüz oy değil:

... bu durumda, aşağıdaki komut dosyasını kullanın:

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); 
          } 
         }); 
         } 
        }); 
  • Kullanım açmış ancak numaralı sınıftan askıya alındı: Bu özel kopya için başka bir salt okunur komut dosyasını kopyalayın ve yapıştırın if-else durumu.

Uzun lafın kısası, benim .jade şablon dosyalarındaki tüm bu JavaScript korumaya çalışırken bir bakım kabus haline geldi ve benim biçimlendirme edilemeyecek kirli görünüyor.

Bunun için bir çözüm nedir? Bu CRUD uygulamaları için böyle yaygın bir senaryo gibi görünüyor. İdeal olarak, tüm javascript'i ayrı bir 'a taşımak istiyorum.js dosya. Ama bazı kod çoğaltmayı kaldırabilirsem, bu da harika olurdu.

Sorun şu ki, inline javascript'i ayrı bir dosyaya taşırsam hangi oyunu derecelendirdiğimi nasıl bilebilirim? Kullanıcının hangi düğmeyi tıkladığını nasıl bilebilirim? N oyunlar için ben N düğmeler, N modal diyaloglar ve N değerlendirme komut dosyalarını satın çünkü

Şu anda belirsizlik yoktur. Herkesin bu programlama tarzı hakkında ne düşündüğüne bakılmaksızın, kodu korumak için korkunç bir yoldur.

Lütfen noobie ile biraz bilgi paylaşın!

Önceden teşekkür ederiz.

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!'); 
       }); 
      }); 
+3

Metin büyük bir duvar ama oldukça iyi bir soru. +1 – Ben

cevap

3

okumak için çok uzun bir yol:

İşte benim games.jade dosyasının tam kod parçacığı bu.

<div id="some_container"> 
    <!-- The following div would be generated in each iteration of the for loop you speak of --> 
    <div class="item-container" data-game-name="Your game name" data-game-id="23"> 
     <span class="button delete-button">X</span> 
    </div> 
</div> 

Ve komut heyeti ile bir şey (büyük ölçüde bağlamaları sayısını en aza indirmek için) olacaktır:

Her neyse, ben ne dediğini özünü almak ve böyle bir format kullanmak düşünüyorum
$(document).ready(function() { 
    $("#some_container").on("click", ".delete-button", function() { 
     var $this = $(this); 
     var $container = $this.closest(".item-container"); 
     var game_name = $container.data("game-name"); 
     var game_id = $container.data("game-id"); 
     // Do whatever with the above 2 variables 
    }); 
}); 

Modal öğelerle ilgili olarak, ne olursa olsun görüntülenecek bir "şablon" içeren bir <div> oluşturabilirsiniz. Daha sonra, herhangi bir tuşa bastığınızda, yukarıdaki gibi mantığı kullanırsınız (öğenin ayrıntılarını almak için ilk üst öğeyi .item-container), bu bilgiyle modaldaki "şablonu" doldurun. Sonra bu şekilde "Tamam" düğme bir milyon kodlanmış şeyler gerektirmez - sadece bir - şablondan bilgi almak ve herhangi bir çağrı yapmak ya da formu göndermek için.

+1

Teşekkürler sunucu veriyi HTML data- * özelliklerine koyarak benzer bir şey.Gerçekten bir oyuna oy veren tüm kullanıcı adları gibi (gizlilikle ilgili endişeler) çok fazla bilgi koyamamama rağmen şablonumda bazı mantık yürüteceğim. data-* özniteliği içinde istemci tarafına geçirilecek bir boole değişkeni True/False ile sonuçlanır. –

İlgili konular