Я изучаю Vuejs (не слишком разбирающийся в Laravel в первую очередь), и я пытаюсь создать простую систему голосования по некоторым задачам. Мне удалось добавить задачи, отредактировать их и удалить, но когда я добавил материал upvote/downvote, количество голосов не изменилось.Laravel 5.3 + Vue Reddit-подобная система голосования
Так вот маршруты Laravel в routes\api.php
:
Route::group(['middleware'=>'api'],function(){
Route::get('tasks', function(){
return \App\Task::latest()->orderBy('created_at', 'desc')->get();
});
Route::get('task/{id}', function($id){
return \App\Task::findOrFail($id);
});
Route::post('task/store', function(Request $request){
return App\Task::create(['body' => $request->input(['body'])]);
});
Route::patch('task/{id}', function(Request $request, $id){
return \App\Task::findOrFail($id)->update(['body' => $request->input(['body'])]);
});
Route::delete('task/{id}', function($id){
return \App\Task::destroy($id);
});
Route::get('task/{id}/votes', function($id){
return \App\Task::findOrFail($id)->votes->get();
});
Route::patch('task/{id}/votes', function(Request $request, $id){
return \App\Task::findOrFail($id)->update(['votes'=> $request->input(['votes'])]);
});
});
миграция для таблицы задач выглядит следующим образом (я использовал SQLite):
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->text('body');
$table->integer('votes')->default(1);
$table->timestamps();
});
Это задачи шаблон компоненты для Vue:
<h1>My Tasks</h1>
<hr>
<h4>New Task</h4>
<form action="#" @submit.prevent="edit ? updateTask(task.id) : createTask()">
<div class="input-group">
<input type="text" name="body" v-model="task.body" v-el:taskinput class="form-control" autofocus>
<span class="input-group-btn">
<button type="submit" class="btn btn-success" v-show="!edit">New Task</button>
<button type="submit" class="btn btn-primary" v-show="edit">Edit Task</button>
</span>
</div>
</form>
<hr>
<hr>
<h3>All Tasks</h3>
<ul class="list-group">
<li class="list-group-item" v-for="task in list">
{{ task.body }}
<button class="btn-success btn-xs" @click="upvote(task.id)" :class="{disabled: upvoted}">Upvote</button>
<span class="label label-primary">{{ task.votes }}</span>
<button class="btn-danger btn-xs" @click="downvote(task.id)" :class="{disabled: downvoted}">Downvote</button>
<span class="pull-right">
<button class="btn-primary btn-xs" @click="showTask(task.id)">Edit Task</button>
<button class="btn-danger btn-xs" @click="deleteTask(task.id)">Delete Task</button>
</span>
</li>
</ul>
И, наконец, сценарий Vue:
export default{
data(){
return{
edit: false,
list: [],
task: {
id: '',
body: '',
votes: Number
},
upvoted: false,
downvoted: false
}
},
ready: function() {
this.fetchTaskList();
},
methods:{
fetchTaskList: function() {
this.$http.get('api/tasks').then(function (response) {
this.list = response.data
});
},
createTask: function() {
this.$http.post('api/task/store', this.task);
this.task.body = '';
this.edit = false;
this.fetchTaskList();
},
updateTask: function (id) {
this.$http.patch('api/task/' + id, this.task);
this.task.body='';
this.edit = false;
this.fetchTaskList();
},
showTask: function (id) {
this.$http.get('api/task/' + id).then(function (response) {
this.task.id = response.data.id;
this.task.body = response.data.body;
});
this.$els.taskinput.focus();
this.edit = true;
},
deleteTask: function (id) {
this.$http.delete('api/task/' + id);
this.fetchTaskList();
},
updateVotes: function (id, votes) {
this.$http.patch('api/task/'+id+'/votes', votes);
},
upvote: function (id) {
this.$http.get('api/task/'+id+'/votes').then(function (response) {
this.task.id = response.data.id;
this.task.votes = response.data.votes + 1;
updateVotes(this.task.id, this.task.votes);
});
this.upvoted = !this.upvoted;
this.downvoted = false;
},
downvote: function (id) {
this.$http.get('api/task/'+id+'/votes').then(function (response) {
this.task.id = response.data.id;
this.task.votes = response.data.votes - 1;
updateVotes(this.task.id, this.task.votes);
});
this.upvoted = false;
this.downvoted = !this.downvoted;
},
}
}
Я предполагаю, что ошибка находится где-то в сценарии Вьет, либо я объявляю голоса неправильно (голоса: Number), или я не могу назвать updateVotes функции от upvote и downvote функции, как я сделал.
Edit: До сих пор не работает, но у меня есть Vue.js DevTools, и это, безусловно, признание голоса: https://snag.gy/sE5gp6.jpg
... но в очень странным образом. Когда я нажимаю upvote, голоса в devtools меняются на «11», а не на 1. Когда я нажимаю downvote, он возвращается к 0. Однако он не изменяется в представлении. Это все после того, как я сделал изменения от:
updateVotes(this.task.id, this.task.votes);
To:
this.updateVotes(this.task.id, this.task.votes);
..as пользователя Dan предложенное, и после изменения параметров:
upvote: function (id) {
this.$http.get('api/task/'+id+'/votes')
To:
upvote: function (id) {
this.$http.get('api/task/'+id)
как я думаю, ранее был g прокладывая только голоса, а затем рассматривая их как объект Task для остальной части функции. То же самое для функции downvote.
Это то, что приходит в консоли Сейчас:
Vue-resource.common.js d39b: 966 PATCH http://localhost:8000/api/task/8/votes 500 (Внутренняя ошибка сервера) (анонимная функция) @ Vue-resource.common.js ? d39b: 966Promise $ 1 @ vue-resource.common.js? d39b: 192xhrClient @ vue-resource.common.js? d39b: 927sendRequest @ vue-resource.common.js? d39b: 1060exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042before @ vue-resource.common.js? d39b: 881exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042timeout @ vue-resource.common.js? D39b: 920exec @ vue-resource.common.js? D39b: 1017next @ vue-resource.common.js? D39b: 1042method @ vue-resource.common.js? D39b: 895exec @ вя-resource.comm on.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042body @ vue-resource.common.js? d39b: 802exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common. js? d39b: 1042jsonp @ vue-resource.common.js? d39b: 867exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042header @ vue-resource.common.js? d39b: 903exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042cors @ vue-resource.common.js?d39b: 777exec @ vue-resource.common.js? d39b: 1017next @ vue-resource.common.js? d39b: 1042 (анонимная функция) @ VM56: 32exec @ vue-resource.common.js? d39b: 1017 (анонимная функция) @ vue-resource.common.js? d39b: 1045Promise $ 1 @ vue-resource.common.js? d39b: 192Client @ vue-resource.common.js? d39b: 1010Http @ vue-resource.common.js? d39b: 1152Http (анонимная функция) @ vue-resource.common.js? d39b: 1188updateVotes @ Tasks.vue? 34c5: 94 (анонимная функция) @ vue.common.js? 4a36: 216 (анонимная функция) @ Tasks.vue? 34c5: 102 localhost /: 1 Непонятно (в обещании) Ответ {url: "api/task/8/votes", body: "↵↵ ↵ ↵↵↵ ↵ ↵", заголовки: Object, status: 500, statusText: "Internal Ошибка сервера "...}
Все еще нет, но я думаю, что это была одна из вещей, которые нужно было изменить. –
У вас есть ошибки в вашей консоли браузера или в файлах журналов? – Dan
Не удалось загрузить ресурс: сервер ответил со статусом 500 (Внутренняя ошибка сервера) http: // localhost: 8000/api/task/7/votes Невлан (в обещании) Ответ. Однако, после вашего первого комментария, я заметил, что ошибся в маршрутах для получения голосов. Я сделал это: Route :: get ('task/{id}/votes', function ($ id) { return \ App \ Task :: findOrFail ($ id) -> vote-> get(); }); , но рассматривал его как объект задачи в скрипте vue. Поэтому я изменил Vue для функций upvote и downvote: . $ Http.get ('api/task /' + id) вместо этого. $ Http.get ('api/task /' + id + '/ голосов ') –