Update the todo list without refreshing the page in express nodejs app

淺唱寂寞╮ 提交于 2021-01-20 18:45:51

问题


I am a newbee to the express nodejs applications. I want to make a todo list. This is how it looks so far. My question is when I add a todo, it takes some time to show the change since it reloads the page. How can I see the change in realtime without reloading the page. Thanks in advance.

in tasks.jade

 h1= title

  .list
    .item.add-task
      div.action
        form(action='/tasks', method='post', id='12345')
          input(type='hidden', value='true', name='all_done')
          input(type='hidden', value=locals._csrf, name='_csrf')
          input(type='submit', class='btn btn-success btn-xs', value='all done')
      form(action='/tasks', method='post')
        input(type='hidden', value=locals._csrf, name='_csrf')
        div.name
          input(type='text', name='name', placeholder='Add a new task')
        div.delete
          input.btn.btn-primary.btn-sm(type="submit", value='add')
    if (tasks.length === 0)
      | No tasks.
    each task, index in tasks
      .item
        div.action
          form(action='/tasks/#{task._id}', method='post')
            input(type='hidden', value=task._id.toString(), name='id')
            input(type='hidden', value='true', name='completed')
            input(type='hidden', value=locals._csrf, name='_csrf')
            input(type='submit', class='btn btn-success btn-xs task-done', value='done')
        div.num
          span=index+1
            |. 
        div.name
          span.name=task.name + ' (Created at: ' + moment(task.createTime).format("YYYY/MM/DD") + ')'
          //- no support for DELETE method in forms
          //- http://amundsen.com/examples/put-delete-forms/
          //- so do XHR request instead from public/javascripts/main.js
        div.delete
          a(class='btn btn-danger btn-xs task-delete', data-task-id=task._id.toString(), data-csrf=locals._csrf) delete

in app.js

app.get('/', routes.index);
app.get('/tasks', tasks.list);
app.post('/tasks', tasks.markAllCompleted)
app.post('/tasks', tasks.add);
app.post('/tasks/:task_id', tasks.markCompleted);
app.delete('/tasks/:task_id', tasks.del);
app.get('/tasks/completed', tasks.completed);

in tasks.js

exports.add = function(req, res, next){
  if (!req.body || !req.body.name) return next(new Error('No data provided.'));
  req.db.tasks.save({
    name: req.body.name,
    createTime: new Date(),
    completed: false
  }, function(error, task){
    if (error) return next(error);
    if (!task) return next(new Error('Failed to save.'));
    console.info('Added %s with id=%s', task.name, task._id);
    res.redirect('/tasks');
  })
};

回答1:


ExpressJS is a server-side framework. That means it serves up views when a browser makes requests for them. In order to prevent the browser from making a full page refresh when interacting with the page you need to look into a client-side framework.

I highly recommend taking a look at AngularJS, but that can be a daunting framework for a beginner. I would definitely first learn JQuery if you haven't already. Many other frameworks either build on top of JQuery directly or mimic some of the patterns employed by JQuery. I would focus on JQuery first and then graduate to a higher-level framework like AngularJS or something similar.

Here is an example of hijacking a form submit with JQuery:

<script type="text/javascript">
  $('#myForm').on('submit', function (event) {
    event.preventDefault(); // Stop the form from causing a page refresh.
    var data = {
      username: $('#username').val(),
      password: $('#password').val()
    };
    $.ajax({
      url: 'http://localhost/my/url',
      data: data,
      method: 'POST'
    }).then(function (response) {
      // Do stuff with the response, like add it to the page dynamically.
      $('body').append(response);
    }).catch(function (err) {
      console.error(err);
    });
  });
</script>

If you put that script tag at the bottom of a page, just before the closing </body> tag, it will hijack a form with the ID myForm and attach an event handler for the submit event. When the form is submitted the event handler will fire first. The first line of the handler event.preventDefault() tells the browser not to perform the default submit behavior and refresh the page. Then after that we create a data object to store the values of the form fields that we are interested in. In this example I use a text input with the ID "username" and a password input with the ID "password". Notice how the string you pass to $() looks a lot like a CSS selector, that's the idea :)

Once we have the data we want to post to the server, we make an AJAX request with the data and we handle the response, or catch any errors if they occur. This AJAX request happens without refreshing the page :)

The reason this script has to be at the bottom of a page is because the elements need to be loaded before it runs. JQuery makes it possible to ensure that the entire document is ready before running scripts.

$(document).on('ready', function (event) {
  // This code won't run until the whole page is ready.
});

If you place your code in that event handler then you can put the script tag anywhere on the page, even in the <head>. JQuery offers a shortcut for that event handler because it's used a lot.

$(function (event) {
  // This is sugar for $(document).on('ready', function () { ... });
});



回答2:


Your server should return JSON instead of rendered HTML. On the front end you should use JavaScript (jQuery and method $.getJSON() for example) to query your server for the updated task list. jQuery will use AJAX to send and receive data from your server without the need to refresh your page. There are many good tutorials online on how to make REST API using Node.js.



来源:https://stackoverflow.com/questions/30646997/update-the-todo-list-without-refreshing-the-page-in-express-nodejs-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!