Renverser booléen sur un clic avec v-for?

voix
2

Débutant à JS et VueCLI donc je vais essayer d'expliquer mieux que je peux. J'utilise Express comme mon arrière-plan.

Je suis en train de changer le booléen dans mon tableau d'objets en cliquant dessus. Je suis en mesure d'accomplir cela, mais lorsque je clique sur un élément de liste différent dans ma boucle v-car il est renversant le booléen dans tous les autres indices de mon tableau. Voici mon code:

Express: / routes:

        // 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);
        });

webapp:

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

et maintenant mon composant 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>

Alors, quand je clique sur mon premier élément de la liste, il modifie la tâche: t1 à vrai, mais si je clique sur le deuxième élément de la liste, il change t1 Retour à False et t2 True. Je ne sais pas exactement ce que je fais mal. Je ne suis même pas sûr que ce soit la meilleure façon de le faire. Mon principal problème est que je ne sais pas pourquoi ça se passe.

Toute aide est très appréciée!

Créé 19/09/2018 à 13:24
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
2

Vous êtes probablement trop compliquer cela.

Tout ce dont tu as besoin c'est

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

Démo ~ https://jsfiddle.net/xy1q0auL/2/

Il n'y a pas (évident) besoin de re-chercher les tâches à chaque fois que vous cliquez sur un. Ceci est la raison pour laquelle vos modifications précédentes sont remis à zéro; c'est parce que vous écrasez toutes les données avec les valeurs non modifiées getTasks().

Créé 19/09/2018 à 13:30
source utilisateur

voix
0

Vous pouvez faire son simple:

 <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 pour le procédé

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

        }
    }
Créé 19/09/2018 à 13:48
source utilisateur

voix
0

Lorsque completeMovie () est appelée, vous envoyez une requête HTTP à votre serveur qui vous envoie va la liste des tâches en arrière sans modification. Je ne comprends pas bien ce que vous essayez est d'atteindre, mais votre rappel dans la promesse n'a pas sens. Dans le rappel vous reaffect la liste « tâches » dans votre vue:

entrez la description d'image ici

Dans ce cas, voici la chronologie des événements que vous devez faire:

  • Lorsque la page client est chargé, Vue Initialisé, le composant vue appelle votre webservice pour obtenir la liste des tâches puis l'imprimer.
  • Puis, quand je clique sur une tâche, vous devez faire un autre appel HTTP à votre webservice (sur une autre route), qui mettra à jour la liste des tâches et se retourner.
  • Puis, dans l'appel de votre composant vue vous reaffect la nouvelle liste des tâches.
Créé 19/09/2018 à 13:36
source utilisateur

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