Clarification of how to use nested schemas/models
michaelsorich opened this issue · comments
I am having a little difficulty understanding how to properly use nested schemas. In the objectschema example I see that there is a nested schema (the field books has a type of [bookSchema]) in the user schema. I am clear on defining the schema but I am not sure how to use this operationally in vue.
For example if I have a form in the template which enables editing of the details of all books in addition to the user details.
-
if I wish to have a button for adding additional books how do I code for this.
e.g. my guess would be to use something like this.user.books.push({ title: 'True Detective' }), but this does not seem to work properly. -
I also am having some issue with v-model on the nested models.
e.g. I am attempting to display fields for all the nested models. In terms of the user/book example it would be something like this for the first book in the array
I'm about to start writing an example for you. I just need some information:
- How does your form structure look like?
- Are you using sub-components in your form?
Thanks - this would be much appreciated.
I currently have a single component which focuses on editing the model (including its nested models). The template contains a single form containing simple fields of the parent model (using html input fields with v-model to bind the appropriate field similar to the example in the vue-contextable README.md), as well fields for each nested models in the array holding the nested models. I have been displaying the same set of fields for each instance of the nested model by iterating over nested models in the array using v-for (at the moment I have each nested model displayed as a row of a table). Next to the collection of fields for each nested model I have button to delete the nested model from the array (delete row from the table). I also have button to add an new nested model to the end of the array (i.e. add row to the bottom of the table in the form).
Hum... it seams that Vue is not tracking changes on class instances but it could also be a bug in the plugin. I'll investigate so don't worry, we'll find a solution soon. I also asked for help here so please be patient.
Here is what I came up with:
- Since Vue.js doesn't recommend modifying a model structure at runtime, the easiest solution to fix this immediatelly is to set the
defaultValue
of each nested field to a non-null value as shown in the example below. This will deeply construct model structure before making the model reactive.
export default new Schema({
fields: {
...
book: {
type: bookSchema,
defaultValue: {} // THIS
},
books: {
type: [bookSchema],
defaultValue: [{}] // THIS
}
}
});
- I've upgraded this plugin with a new
modelData
configuration option which pre-populates a model (preferred way).
export default {
contextable: {
validate: [
{
...
modelData: {},
}
]
},
...
}
- Two new reactive methods are also available -
$build
and$populate
.
// using the $build method
export default {
contextable: {
...
},
beforeCreate () {
this.user.book = {title: 'asdasd'}; // sets field's data but removes reactivity
this.user.books = [{title: 'asdasd'}]; // sets field's data but removes reactivity
this.user.$build(); // rebuilds model reactivity
}
}
// using the $populate method
export default {
contextable: {
...
},
beforeCreate () {
this.user.$populate({ // sets model fields and runs $build method
name: null,
book: {},
books: [{}]
});
}
}
- The new
$build
method will help you build a form with dynamic fields as well. See the example for details.
Features have been published and a new version of this package is now available for download. Please let me know if this works for you.
Cool :)