Invertir booleano al hacer clic con v-a?

votos
2

Principiante a JS y VueCLI así que voy a tratar de explicar lo mejor que pueda. Estoy usando Express como mi back-end.

Estoy intentando cambiar el booleano en mi serie de objetos en clic. Soy capaz de lograr eso, pero cuando hago clic en un elemento de lista diferente en mi v-bucle que está volteando el booleano en todos los demás índices de mi matriz. Aquí está mi código:

Expresar: / rutas:

        // fake data store
        const tasks = [
           { id: 1, task: 't1', completed: false},
           { id: 2, task: 't2', completed: false},
           { id: 3, task: 't3', completed: false}
        ];

        /**
        * GET handler for /tasks route
        * @returns {Array.<{id: Number, task: String, completed: Boolean}>} array of task objects 
        */
        router.get('/', (req, res) => {
           res.send(tasks);
        });

Aplicación Web:

        /**
        * GET /tasks
        * @returns Promise => {Array.<{id: Number, task: String, completed: Boolean}>} array of task objects
        */
        export function getTasks() {
           return request('tasks');
        }

y ahora mi componente Vue:

        <template>
        <div id=tasks>
            <h2>Movies to Add</h2>
            <ul class=todo-list>
            <li v-for='task in tasks' :id=task.id v-on:click=completeMovie($event) :key='task.id' class=todo-list__li>
                <input class=todo-list__input type=checkbox :name='task.task' :id=task.task>
                <div class=todo-list__checkbox>
                <span class=todo-list__checkbox-inner><i></i></span>
                </div>
                <label :for='task.task'>{{ task.task }}</label>
            </li>
            </ul>
        </div>
        </template>

        <script>
        import {getTasks} from './../../services/tasks';

        export default {
        name: 'TaskList',
        data: function() {
            return {
            tasks: []
            };
        },
        created: function() {
            getTasks()
            .then(res => this.tasks = res);
        },
        methods: {
            completeMovie: function (event) {
            var taskId = event.currentTarget.id -1;

            getTasks()
                .then((res) => {
                this.tasks = res;
                res[taskId].completed = !res[taskId].completed;
                });
            }
        }
        }
        </script>

Así que cuando hago clic en mi primer elemento de la lista cambia la tarea: t1 a True pero si hago clic en el segundo elemento de la lista se cambia de nuevo a t1 y t2 False a True. No estoy seguro exactamente lo que estoy haciendo mal. Ni siquiera estoy seguro de que esta es la mejor manera de hacer esto. Mi principal problema es que no estoy seguro de por qué está sucediendo.

¡Cualquier ayuda es muy apreciada!

Publicado el 19/09/2018 a las 13:24
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
2

Usted es probablemente complicar esto.

Todo lo que necesitas es

<li v-for="task in tasks" :key="task.id" 
    @click="task.completed = !task.completed" 
    class="todo-list__li">

Demostración ~ https://jsfiddle.net/xy1q0auL/2/

No hay (obvio) es necesario volver a buscar a los tareas cada vez que se hace clic en uno. Es por esto que los cambios anteriores se ponen a cero; es porque se sobrescribe todos los datos con los valores modificados de getTasks().

Respondida el 19/09/2018 a las 13:30
fuente por usuario

votos
0

Usted puede hacer su simplemente:

 <li v-for='task in tasks' :id="task.id" v-on:click="completeMovie(task.id)" :key='task.id' class="todo-list__li">
            <input class="todo-list__input" type="checkbox" :name='task.task' :id="task.task">
            <div class="todo-list__checkbox">
            <span class="todo-list__checkbox-inner"><i></i></span>
            </div>
            <label :for='task.task'>{{ task.task }}</label>
        </li>

Ans para el método

completeMovie: function ($taskId) {
        this.tasks[$taskId].completed = !this.tasks[$taskId].completed;

        }
    }
Respondida el 19/09/2018 a las 13:48
fuente por usuario

votos
0

Cuando se llama completeMovie (), se envía una petición HTTP al servidor que se va a enviar la lista de tareas que volver inalterada. No entiendo claramente lo que usted está tratando de lograr, pero su devolución de llamada en la promesa no tiene sens. En la devolución de llamada que destine los lista de "tareas" en su vue:

introducir descripción de la imagen aquí

En este caso, aquí es el calendario de eventos que tiene que hacer:

  • Cuando se carga la página del cliente, Vue inicializado, el componente vue llama a su servicio web para obtener la lista de tareas y luego imprimirlo.
  • A continuación, al hacer clic en una tarea, usted tiene que hacer una llamada de otra HTTP a su servicio web (en otra ruta), que actualizará la lista de tareas y lo devolverá.
  • Luego, en la llamada de su componente vue que destine los nueva lista de tareas.
Respondida el 19/09/2018 a las 13:36
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more