Vue-Draggable & Acts As List - Как обновить всю позицию списка? - PullRequest
0 голосов
/ 13 мая 2019

В моем проекте у меня есть бэкэнд API Rails, где я использую гем act_as_list и интерфейс Vue, где я использую пакет Vue Draggable.

Акт перетаскивания работает, и я вижу, что запрос PUT отправляется на мой сервер. Однако есть пара странностей:

Сценарий 1: Я перетаскиваю элемент из положения 1 в положение 2 (поэтому они по существу переворачиваются). Запрос PUT отправляется, однако фактическое обновление не происходит.

Сценарий 2: Я перетаскиваю элемент из позиции 1 в позицию 3. Это означает, что позиция 2 должна сместиться до 1, 2 должна сместиться до 1, а 1 - в 3 (надеюсь, это имеет смысл). Это странно, потому что иногда Я вижу, что обновление происходит на моем сервере, но не каждый раз.

Мне нужно обновить весь список при перетаскивании.

TodoList.vue

<template>
    <div class="todos-container" v-if='trips.loaded'>
      <draggable 
        :list='todoList' 
        :options='{animation:150}'
        tag='ul' 
        class='list-group' 
        @change='changed(todoList, $event)'
      >
        <transition-group type='transition'>
          <li v-for='(todo, index) in todoList' :key='todo.id' class='list-group-item'>
            <v-icon class='drag-handle'>drag_handle</v-icon>
            <v-checkbox
              v-model="todoList[index].completed"
              :ripple='false'
              :label='`${todo.title}`'
              color='primary'
              @change='handleTodoClick(todo, index)'
            />
            <v-icon class='remove-todo' @click='handleTodoDelete(todo, index)'>close</v-icon>
          </li>

        </transition-group>
      </draggable>
    </div>
  </todo-list-styles>
</template>

<script>
  import { mapActions } from 'vuex';
  import draggable from 'vuedraggable';

  export default {
    props: {
      trips: {
        type    : Object,
      },
      index: {
        type    : Number,
        required: true,
      }
    },
    computed: {
      todoList() {
        return this.trips.data[this.index].todos;
      }
    },
    methods: {
      ...mapActions('trips', [
        'updateTodoPosition'
      ]),
      handleTodoClick: function(todo, index) {
        console.log('checked')
      },
      handleTodoDelete: function(todo, index) {
        console.log('clicked');
      },
      changed: function(todoList, $event) {
        const {oldIndex, newIndex} = $event.moved;
        const todo = todoList[newIndex];
        const payload = {
          oldIndex,
          newIndex,
          todo,
        };
        this.updateTodoPosition(payload);
      },
    },
    components: {
      draggable,
    },
  }
</script>

Params

Started PUT "/2/update_todo_position" for 127.0.0.1 at 2019-05-13 08:46:09 -0500
Processing by V1::TripsController#update_todo_position as */*
  Parameters: {"oldIndex"=>0, "newIndex"=>2, "todo"=>{"id"=>2, "title"=>"Book Car Rental", "completed"=>true, "position"=>2}, "todo_id"=>"2", "trip"=>{"oldIndex"=>0, "newIndex"=>2, "todo"=>{"id"=>2, "title"=>"Book Car Rental", "completed"=>true, "position"=>2}}}
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  TodoItem Load (0.2ms)  SELECT  "todo_items".* FROM "todo_items" WHERE "todo_items"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
   (0.2ms)  BEGIN
  CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  UpcomingHike Load (0.3ms)  SELECT  "upcoming_hikes".* FROM "upcoming_hikes" WHERE "upcoming_hikes"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.2ms)  COMMIT
Completed 200 OK in 5ms (ActiveRecord: 1.1ms)

trips_controller.rb

module V1
  class TripsController < ApplicationController

    ...

    def update_todo_position
      # TODO: Figure out why position being saved is incorrect
      todo = TodoItem.find(params[:todo][:id])
      todo.update!(position: params[:newIndex])
      head :ok
    end

    ...

  end
end

1 Ответ

0 голосов
/ 15 мая 2019

Закончил путь, которым я не горжусь, но работаю.Со своего внешнего интерфейса я отправляю весь недавно упорядоченный список.Затем в моем контроллере я прокручиваю каждую из них и индивидуально обновляю их позицию.Определенно не рекомендуемый VueDraggable способ сделать это, и абсолютно не эффективный способ обработки этого в моем контроллере:

метод компонента vue:

changed: function(todoList, $event) {
        const {newIndex} = $event.moved;
        const todo = todoList[newIndex];
        const newListOrder = JSON.stringify(this.todoList.map(todo => todo.id));
        const payload = {
          todo,
          newListOrder,
        }
        this.updateTodoPosition(payload);
      },

контроллер:

def update_todo_position
      newListIds = params[:_json]
      newListIds.each.with_index(1) do |todo, index|
        todo = TodoItem.find(todo)
        todo.update(position: (index))
      end
      head :ok
    end

Если у кого-нибудь есть предложения, я бы с удовольствием их услышал!

...