Creating models dynamically

This is a little bit complicated to explain. I need to create an object with properties from a dynamic html code. Let me explain it with an example.

I have an object with my data like this

var myObject = {Field1: 'Value1', Field2: 'Value2'};

I have an array with my object properties like this:

var myArray = ['Field1', 'Field2'];

I use the array to generate <input> in a for loop like this:

<div v-for="property in myArray">
    <input type="text" :value="myObject[property]" />
</div>

Now, I need to get the values from the generated inputs (can be an object or an array).

I know i can just simply take myObject but the thing is that the values might change (The user can alter the data because is an input which is the right approach). Also I dont want to bind the inputs to myObject because even in the input values change, myObject need to remain as it initial state.

The question is how can I create a new object and bind my inputs to that new object?

Upvotes: 1

Views: 143

Answers (2)

Sphinx
Sphinx

Reputation: 10729

The solutions:

  1. v-model one computed like below, it has one disadvantage, Vue won't catch the modification to re-render.

  2. create one clone myOjbect then watch it, if change, do something you like.

  3. similar with solution 2: using v-bind, then bind input event to assign the value to another object or something else . PS: v-model do same thing like this.

app = new Vue({ //not vue, it is Vue
el: "#app",
  data() {
    return {
      myObject: {Field1: 'Value1', Field2: 'Value2'},
      myArray: ['Field1', 'Field2'],
      copyMyObject: {}, //solution 2
      copyMyObject1: {} //solution 3
    }
  },
  computed: {//solution 1
    computedObject: function(){
      return Object.assign({}, this.myObject)
    }
  },
  mounted: function(){ //solution 2
    this.copyMyObject= Object.assign({}, this.myObject)
    this.copyMyObject1= Object.assign({}, this.myObject)
  },
  watch: {//solution 2
    copyMyObject: function (newValue, oldValue){
      console.log('copyMyObject', newValue)
      //do something else you'd like
    }
  },
  methods: {
    getObject: function () {//solution 1
      console.log('computedObject', this.computedObject)
      console.log('myObject', this.myObject)
    }
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
  <button @click="getObject()">Click me!</button>
  <p>The disadvantage: {{computedObject}}</p>
  <div v-for="property in myArray">
      <input type="text" v-model="computedObject[property]" />
  </div>
  <p>Org: {{myObject}}</p>
  <p>Copy: {{copyMyObject}}</p>
  <div v-for="property in myArray">
      <input type="text" v-model="copyMyObject[property]" />
  </div>
  <p>Copy: {{copyMyObject1}}</p>
  <div v-for="property in myArray">
      <input type="text" v-bind:value="copyMyObject1[property]" @input="copyMyObject1[property] = $event.target.value" />
  </div>
</div>

Upvotes: 1

Roy J
Roy J

Reputation: 43899

You create the object from the original object:

data: {
  objectValues = Object.assign({}, myObject)
}

then you can use that object in your template:

<div v-for="property in myArray">
    <input type="text" v-model="objectValues[property]" />
</div>

Upvotes: 1

Related Questions