mirror of
https://github.com/kataras/iris.git
synced 2025-03-14 11:06:27 +01:00
_examples/tutorial/vuejs-todo-mvc finished, live updates on all clients with the same session id (u can do it with login id for example) and memory storage on the server side, works perfectly and amazing fast, nice vue and iris
Former-commit-id: 0bb930f43e2d70a707d3c6880dc255acd78debf2
This commit is contained in:
parent
e1c65d23fb
commit
d31b8c5274
|
@ -32,7 +32,8 @@
|
||||||
<ul class="todo-list">
|
<ul class="todo-list">
|
||||||
<li v-for="todo in filteredTodos" class="todo" :key="todo.id" :class="{ completed: todo.completed, editing: todo == editedTodo }">
|
<li v-for="todo in filteredTodos" class="todo" :key="todo.id" :class="{ completed: todo.completed, editing: todo == editedTodo }">
|
||||||
<div class="view">
|
<div class="view">
|
||||||
<input class="toggle" type="checkbox" v-model="todo.completed">
|
<!-- v-model="todo.completed" -->
|
||||||
|
<input class="toggle" type="checkbox" @click="completeTodo(todo)">
|
||||||
<label @dblclick="editTodo(todo)">{{ todo.title }}</label>
|
<label @dblclick="editTodo(todo)">{{ todo.title }}</label>
|
||||||
<button class="destroy" @click="removeTodo(todo)"></button>
|
<button class="destroy" @click="removeTodo(todo)"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,32 +1,35 @@
|
||||||
// Full spec-compliant TodoMVC with Iris
|
// Full spec-compliant TodoMVC with Iris
|
||||||
// and hash-based routing in ~120 effective lines of JavaScript.
|
// and hash-based routing in ~120 effective lines of JavaScript.
|
||||||
|
|
||||||
// var socket = new Ws("ws://localhost:8080/todos/sync");
|
var socket = new Ws("ws://localhost:8080/todos/sync");
|
||||||
|
|
||||||
// socket.On("saved", function () {
|
socket.On("saved", function () {
|
||||||
// console.log("receive: on saved");
|
// console.log("receive: on saved");
|
||||||
// todoStorage.fetch();
|
fetchTodos(function (items) {
|
||||||
// });
|
app.todos = items
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
var todos = [];
|
|
||||||
|
function fetchTodos(onComplete) {
|
||||||
|
axios.get("/todos").then(response => {
|
||||||
|
if (response.data == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
onComplete(response.data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var todoStorage = {
|
var todoStorage = {
|
||||||
fetch: function () {
|
fetch: function () {
|
||||||
axios.get("/todos").then(response => {
|
var todos = [];
|
||||||
if (response.data == null) {
|
fetchTodos(function (items) {
|
||||||
return;
|
for (var i = 0; i < items.length; i++) {
|
||||||
}
|
todos.push(items[i]);
|
||||||
for (var i = 0; i < response.data.length; i++) {
|
|
||||||
// if (todos.length <=i || todos[i] === null) {
|
|
||||||
// todos.push(response.data[i]);
|
|
||||||
// } else {
|
|
||||||
// todos[i] = response.data[i];
|
|
||||||
// }
|
|
||||||
todos.push(response.data[i]);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return todos;
|
||||||
return todos
|
|
||||||
},
|
},
|
||||||
save: function (todos) {
|
save: function (todos) {
|
||||||
axios.post("/todos", JSON.stringify(todos)).then(response => {
|
axios.post("/todos", JSON.stringify(todos)).then(response => {
|
||||||
|
@ -35,7 +38,7 @@ var todoStorage = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// console.log("send: save");
|
// console.log("send: save");
|
||||||
// socket.Emit("save")
|
socket.Emit("save")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,27 +65,27 @@ var app = new Vue({
|
||||||
// app initial state
|
// app initial state
|
||||||
data: {
|
data: {
|
||||||
todos: todoStorage.fetch(),
|
todos: todoStorage.fetch(),
|
||||||
|
hasChanges: false,
|
||||||
newTodo: '',
|
newTodo: '',
|
||||||
editedTodo: null,
|
editedTodo: null,
|
||||||
visibility: 'all'
|
visibility: 'all'
|
||||||
},
|
},
|
||||||
|
|
||||||
// watch todos change for persistence
|
// we will not use the "watch" as it works with the fields like "hasChanges"
|
||||||
watch: {
|
// and callbacks to make it true but let's keep things very simple as it's just a small getting started.
|
||||||
todos: {
|
// // watch todos change for persistence
|
||||||
handler: function (todos) {
|
// watch: {
|
||||||
// // saved by this client.
|
// todos: {
|
||||||
// if (todos[todos.length - 1].id === 0) {
|
// handler: function (todos) {
|
||||||
// todoStorage.save(todos);
|
// if (app.hasChanges) {
|
||||||
// } else {
|
// todoStorage.save(todos);
|
||||||
// console.log("item cannot be saved, already exists.");
|
// app.hasChanges = false;
|
||||||
// console.log(todos[todos.length - 1]);
|
// }
|
||||||
// }
|
|
||||||
todoStorage.save(todos);
|
// },
|
||||||
},
|
// deep: true
|
||||||
deep: true
|
// }
|
||||||
}
|
// },
|
||||||
},
|
|
||||||
|
|
||||||
// computed properties
|
// computed properties
|
||||||
// http://vuejs.org/guide/computed.html
|
// http://vuejs.org/guide/computed.html
|
||||||
|
@ -101,6 +104,7 @@ var app = new Vue({
|
||||||
this.todos.forEach(function (todo) {
|
this.todos.forEach(function (todo) {
|
||||||
todo.completed = value
|
todo.completed = value
|
||||||
})
|
})
|
||||||
|
this.notifyChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -114,21 +118,34 @@ var app = new Vue({
|
||||||
// methods that implement data logic.
|
// methods that implement data logic.
|
||||||
// note there's no DOM manipulation here at all.
|
// note there's no DOM manipulation here at all.
|
||||||
methods: {
|
methods: {
|
||||||
|
notifyChange: function () {
|
||||||
|
todoStorage.save(this.todos)
|
||||||
|
},
|
||||||
addTodo: function () {
|
addTodo: function () {
|
||||||
var value = this.newTodo && this.newTodo.trim()
|
var value = this.newTodo && this.newTodo.trim()
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.todos.push({
|
this.todos.push({
|
||||||
id: 0, // just for the client-side.
|
id: this.todos.length + 1, // just for the client-side.
|
||||||
title: value,
|
title: value,
|
||||||
completed: false
|
completed: false
|
||||||
})
|
})
|
||||||
this.newTodo = ''
|
this.newTodo = ''
|
||||||
|
this.notifyChange();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
completeTodo: function (todo) {
|
||||||
|
if (todo.completed) {
|
||||||
|
todo.completed = false;
|
||||||
|
} else {
|
||||||
|
todo.completed = true;
|
||||||
|
}
|
||||||
|
this.notifyChange();
|
||||||
|
},
|
||||||
removeTodo: function (todo) {
|
removeTodo: function (todo) {
|
||||||
this.todos.splice(this.todos.indexOf(todo), 1)
|
this.todos.splice(this.todos.indexOf(todo), 1)
|
||||||
|
this.notifyChange();
|
||||||
},
|
},
|
||||||
|
|
||||||
editTodo: function (todo) {
|
editTodo: function (todo) {
|
||||||
|
@ -141,10 +158,11 @@ var app = new Vue({
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.editedTodo = null
|
this.editedTodo = null
|
||||||
todo.title = todo.title.trim()
|
todo.title = todo.title.trim();
|
||||||
if (!todo.title) {
|
if (!todo.title) {
|
||||||
this.removeTodo(todo)
|
this.removeTodo(todo);
|
||||||
}
|
}
|
||||||
|
this.notifyChange();
|
||||||
},
|
},
|
||||||
|
|
||||||
cancelEdit: function (todo) {
|
cancelEdit: function (todo) {
|
||||||
|
@ -153,7 +171,8 @@ var app = new Vue({
|
||||||
},
|
},
|
||||||
|
|
||||||
removeCompleted: function () {
|
removeCompleted: function () {
|
||||||
this.todos = filters.active(this.todos)
|
this.todos = filters.active(this.todos);
|
||||||
|
this.notifyChange();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user