javascript - Vue.js rovnaký formulár pre pridanie a úpravu


Som nováčik vo vue.js a snažím sa rozšíriť niektoré dokončené tutoriály. Bojujem s tým už tri hodiny a som frustrovaný. Pre informáciu, používam firebase, ale nie som si istý, či to tu naozaj záleží.

Takže, mám CRUD aplikáciu na zoznam filmov (povedal som vám, že je to základné!). Na vrchu stránky je formulár, kde môžete pridávať filmy, a pod ním tabuľka, kde sú uvedené nové záznamy. Toto funguje dobre.

Pridal som tlačidlá Upraviť a Vymazať k každému riadku v tabuľke. Funkcia vymazania funguje. Ale problém je vo funkcii úpravy.

Chcel by som použiť v-if na počiatočnom formulári, aby sa spustili rôzne metódy (uložiť, upraviť) a zobrazili sa rôzne tlačidlá (Pridať, Uložiť, Zrušiť).

Nie som si istý, ako získať prístup k objektom, aby som to urobil, skúšal som pár vecí a v-if hovorí, že objekt nie je definovaný.

ďakujem za prečítanie, prosím, opýtajte sa čokoľvek, čo potrebujete.

import './firebase' // this has my credententials and initializeApp
import Vue from 'vue'
import App from './App'
import VueFire from 'vuefire'

Vue.use(VueFire)
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})
<template>
  <div id="app" class="container">
    <div class="page-header">
      <h1>Vue Movies</h1>
    </div>
 
    <div class="panel panel-default">
      <div class="panel-heading">
        <h3>Add Movie</h3>
      </div>
 
      <div class="panel-body">

        <div v-if="!isEditing">
          <form id="form" class="form-inline" v-on:submit.prevent="addMovie">
            <div class="form-group">
              <label for="movieTitle">Title:</label>
              <input type="text" id="movieTitle" class="form-control" v-model="newMovie.title">
            </div>
            <div class="form-group">
              <label for="movieDirector">Director:</label>
              <input type="text" id="movieDirector" class="form-control" v-model="newMovie.director">
            </div>
            <div class="form-group">
              <label for="movieUrl">URL:</label>
              <input type="text" id="movieUrl" class="form-control" v-model="newMovie.url">
            </div>
            <input type="submit" class="btn btn-primary" value="Add Movie">
          </form>
        </div>

        <div v-else>
          <form id="form" class="form-inline" v-on:submit.prevent="saveEdit(movie)">
            <div class="form-group">
              <label for="movieTitle">Title:</label>
              <input type="text" id="movieTitle" class="form-control" v-model="movie.title">
            </div>
            <div class="form-group">
              <label for="movieDirector">Director:</label>
              <input type="text" id="movieDirector" class="form-control" v-model="movie.director">
            </div>
            <div class="form-group">
              <label for="movieUrl">URL:</label>
              <input type="text" id="movieUrl" class="form-control" v-model="movie.url">
            </div>
            <input type="submit" class="btn btn-primary" value="Save">
            <button v-on:click="cancelEdit(movie['.key'])">Cancel</button>
          </form>
        </div>

      </div>

    </div>
 
    <div class="panel panel-default">
      <div class="panel-heading">
        <h3>Movies List</h3>
      </div>
      <div class="panel-body">
        <table class="table table-stripped">
          <thead>
            <tr>
              <th>Title</th>
              <th>director</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="movie in movies">

              <td>
                <a v-bind:href="movie.url" v-bind:key="movie['.key']" target="_blank">{{movie.title}}</a>
              </td>
              <td>
                {{movie.director}}
              </td>
              <td>
                <button v-on:click="editMovie(movie)">Edit</button>
              </td>
              <td>
                <button v-on:click="removeMovie(movie)">Remove</button>
              </td>

            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<script>

import { moviesRef } from './firebase'

export default {
  name: 'app',
  firebase: {
    movies: moviesRef
  },
  data () {
    return {
      isEditing: false, // maybe this helps?
      newMovie: {
        title: '',
        director: '',
        url: 'http://',
        edit: false // or maybe this??
      }
    }
  },
  methods: {
    addMovie: function() {
      moviesRef.push( this.newMovie )
      this.newMovie.title = '',
      this.newMovie.director = '',
      this.newMovie.url = 'http://'
      this.newMovie.edit = false
    },
    editMovie: function (movie){
      moviesRef.child(movie['.key']).update({ edit:true }); // can't access this one with v-if, not sure why
      //this.newMovie = movie;
    },
    removeMovie: function (movie) {
      moviesRef.child(movie['.key']).remove()
    },
    cancelEdit(key){
      moviesRef.child(key).update({ edit:false })
    },
    saveEdit(movie){
      const key = movie['key'];
      moviesRef.child(key).set({
        title    : movie.title,
        director : movie.director,
        url      : movie.url,
        edit     : movie.edit
      })
    }
  }
}

</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Odpoveď č. 1

Mali by ste zmeniť isEditing na true, keď sa klikne na tlačidlo Edit, a mali by ste definovať dáta movie.

editMovie: function (movie){
  ...
  this.movie = Vue.util.extend({}, movie); // deep clone to prevent modify the original object
  this.isEditing = true;
},

Odpoveď č. 2

Ako sa navrhuje v komentároch (od Bena), pridal som deklaráciu filmu do počiatočného dátového objektu. Takže teraz to vyzerá takto:

data () {
    return {
      isEditing: false,
      newMovie: {
        title: '',
        director: '',
        url: 'http://',
        edit: false
      },
      movie: {
        edit: false
      }
    }
  },

Teraz v-if funguje úplne v poriadku, takto:

<div v-if="!movie.edit">

„is Editing“ už nebolo potrebné, takže som to odstránil.