I'm using Express and Jade on top of Node.js to build a web app. I have an Express route that pulls a list of words from a database and sends the list to Jade as an array object for rendering. I want to render my Jade page so that on the client side each word, when clicked on, will send a distinct message back to the server.

My code thus far looks something like this...

./routes/show_words_to_user.js:

exports.render_page = function(req, res){
    DBClient.query('SELECT Word FROM Words;', function(err, result){
        res.render('PageTitle',{WordList:result,UserData:UserObj});
    });
};

./views/words.jade:

ul
    each word in WordList
        li= word

./routes/update_preference.js (expects to receive a message from client):

exports.update_word = function(req, res){
    DBClient.query('UPDATE Words SET UserLiked = 1 WHERE Word=($1) and UserId=($2)',
        [ClickedWord,UserId],function(err, result){
        res.send('Your word was updated.');
    };
};

I need each word that is rendered in my Jade list to act as a hyperlink that will send a message to the server containing 1) the name of the word that was clicked on and 2) the user id that the server originally passed to Jade.

My first thought was to render each list item as a hyperlink and use jQuery to bind a response function to each item. However, When I used jQuery on the client side, I lost the ability to specify a distinct function for each item in the list.

My second thought was to do inline JavaScript and set onclick= some function that I can pass the text of the list item to, like so:

ul
    each word in WordList
        a(href='#',onclick='js_that_sends_word_to_update_preference(\'' + word + '\')')= word

This had undesirable behavior as well, as the page jumps to the top every time I click on a link. I'd thought I could stop this, but I am not able to call the "e.preventdefault" function for the hyperlink because I am passing a string, and not an event, to the onclick function.

I feel like I'm going about this in completely the wrong way. There's probably a clean method for rendering iterative functions in Jade, but it's escaping me.

有帮助吗?

解决方案 2

I think I've found a workaround. It's not very pretty, but it does avoid inline javascript.

./views/words.jade:

each word in WordList
    a(href='#', class='contact_server') word

./public/javascripts/word_clientside.js:

$('.contact_server').click(function(){
    $.get('/update_preference?clicked_word=' + this.innerHTML, function(data){
        alert('Server returned: ' + data);
    });
    return false; //prevents hyperlink from returning to top of page
});

Essentially, I use jQuery to bind a function to each hyperlink in my list. The function grabs the inner HTML of the hyperlink that was clicked and sends that inner HTML to the server.

If anyone knows of a cleaner/more conventional way to do this, I'm wide open to suggestions.

Update:

I think I've found a cleaner way to do this. I'm just taking whatever item-specific data I'll need to return to the server and embedding it in a custom data-* attribute, like so:

http://www.w3schools.com/tags/att_global_data.asp

其他提示

So your problem isn't really to do with node or Jade, but with the HTML and/or JavaScript you want to generate?

A simple way would be a normal link, just as you orignally considered:

each word in WordList
  a(href='/update_preference?clicked_word=' + encodeURIComponent(word), class='contact_server')= word

(I hope the Jade syntax is ok, I have only little expierence with it)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top