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