2012-11-27 6 views
6

Dies ist eine etwas noob-Frage für jemanden, der ein paar Jahre Erfahrung in Web-Entwicklung hatte, aber nachdem ich die Antwort weder auf Programmierer Stack Exchange noch Google gefunden habe, habe ich beschlossen, es hier zu fragen.Wie kann man Inline-Javascript von dynamisch generiertem Inhalt in Express/Node.js trennen?

Ich verwende Express Web-Framework für Node.js, aber diese Frage ist in jedem Web-Framework oder Programmiersprache nicht spezifisch.

Hier ist eine Liste der Spiele, die aus der Datenbank abgefragt werden. Jedes Spiel Einheit ist eine einzelne Tabellenzeile, eine for-Schleife erzeugt unter Verwendung:

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

enter image description here

Jeder Rating Block sowie jeder Kaufen Knopf-/modalen Dialog erzeugt werden durch die for-Schleife mit einer ID, die dem Spiel entspricht. Zum Beispiel wird die Schaltfläche für Assassin's Creed haben ID = "Preis-Assassinen-Creed". # {variable} - so verweisen Sie auf eine Variable in Jade, die vom Server übergeben wird.

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

und

.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 

und

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

Multiply, dass durch die Anzahl der Spiele und das ist, wie viele Inline-Scripts ich auf der einen Seite haben.

Schlimmer noch, ich habe für die folgenden Fälle zu berücksichtigen:

  • Benutzer sind nicht angemeldet in: Anzeige über Rating-Skript im schreibgeschützten Modus.
  • des Benutzer angemeldet in, aber noch nicht gestimmt:

... in diesem Fall benutzen Sie das folgende Skript:

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); 
          } 
         }); 
         } 
        }); 
  • den Benutzer angemeldet in aber von der Bewertung suspendiert: Kopieren und fügen Sie noch ein weiteres schreibgeschütztes Skript für diesen bestimmten if-else Zustand.

Lange Rede kurzer Sinn, es ist ein Albtraum werden versuchen, dieses JavaScript in meinen .jade Template-Dateien zu halten und meine Markup sieht unannehmbar schmutzig.

Was ist eine Lösung dafür? Dies scheint ein typisches Szenario für CRUD-Anwendungen zu sein. Idealerweise möchte ich alle Javascript in einen separaten verschieben.js Datei. Aber wenn ich etwas Code kopieren könnte, wäre das auch großartig.

Das Problem ist, wenn ich Inline-Javascript in eine separate Datei verschiebe, woher weiß ich, welches Spiel ich bewerte? Woher weiß ich, auf welche Schaltfläche "Kaufen" der Nutzer geklickt hat?

Im Moment gibt es keine Zweideutigkeit, weil für N Spiele I N Tasten kaufen haben, N modale Dialoge und N Bewertung Skripte. Unabhängig davon, was man von dieser Art der Programmierung hält, ist es eine schreckliche Art, den Code zu pflegen.

Bitte teilen Sie einige Einblicke mit einem Noobie!

Vielen Dank im Voraus.

ist die komplette Code-Snippet meiner games.jade Datei:

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

Große Wand des Textes, aber eine ziemlich gute Frage +1 – Ben

Antwort

3

, die viel zu lange war zu lesen. Wie auch immer, ich glaube, ich den Kern von dem, was Sie sagen, und ein Format wie folgt verwenden würde:

<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> 

Und Ihr Skript wäre etwas mit Delegation (minimieren die Anzahl der Bindungen stark):

$(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 
    }); 
}); 

Wie für die modale Zeug, könnten Sie entweder eine <div> erstellen, die eine "Vorlage" für was für was auch immer anzuzeigen hat. Dann, wenn Sie auf eine beliebige Schaltfläche klicken, verwenden Sie Logik wie oben (erhalten die erste übergeordnete .item-container, um Details über das Element zu erhalten, füllen sie die "Vorlage" im Modal mit dieser Information. Dann auf diese Weise, das "OK" Button braucht keine Million hardcoded Dinge - nur eine - schnappen Sie sich die Informationen aus der Vorlage und machen Sie einen Anruf oder senden Sie das Formular

+1

Danke, ich endete mit etwas Ähnliches, indem ich meine Serverdaten in HTML-Daten * -Attribute einfüge.Obwohl ich nicht zu viele Informationen eingeben kann, wie alle Benutzernamen, die über ein bestimmtes Spiel abgestimmt haben (Datenschutzbedenken), mache ich am Ende eine Logik in meiner Vorlage Ergebnis ist eine boolesche Variable True/False, die an das clientseitige Attribut data-* übergeben wird. –

Verwandte Themen