2016-09-28 6 views
5

Я изучаю 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 Ошибка сервера "...}

ответ

1

ли работа, если заменить:

updateVotes(this.task.id, this.task.votes); 

С

this.updateVotes(this.task.id, this.task.votes); 
+0

Все еще нет, но я думаю, что это была одна из вещей, которые нужно было изменить. –

+0

У вас есть ошибки в вашей консоли браузера или в файлах журналов? – Dan

+0

Не удалось загрузить ресурс: сервер ответил со статусом 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 + '/ голосов ') –

1

(Опубликовано от имени О.П.).

Проблема решена. Я не добавил protected $fillable = ['votes'] в модель задачи.

Смежные вопросы