Vue.js, вложенный для привязки модели поля входного цикла
В этом примере я разрешаю пользователю создавать собственный типизированный список разделов. Каждый тип имеет свои собственные поля формы. Поля формы отображаются правильно, однако, если я введу данные в одно из полей после того, как создаю два дублирующих раздела, оба ввода будут обновлены с введенным текстом. Это не предполагаемый результат.
Вместо этого каждый раздел должен обновлять содержимое данных своего поля формы индивидуально, и он должен отражать значение, сохраненное в разделе data.section, связанном с ним.
Что мне не хватает?
Laravel View
{{Form::open(['route' => 'api.post.store', 'class' => 'form-horizontal'])}}
<fieldset>
<div id="legend">
<legend class="">Register</legend>
</div>
<div :key="section.id" v-for="(index,section) in sections" class="control-group form-group-lg">
<div class="form-header">
<h3>@{{ section.label }}</h3>
</div>
<pre>@{{ section | json }}</pre>
<div v-for="field in section.fields" :key="field.id">
<div class="text-field" v-show="field.inputType == 'text'">
<label class="control-label" :for="section.name">@{{ field.label }}</label>
<div class="controls">
<input v-model="field.data.content" class="input-xlarge form-control">
<p class="help-block">@{{ field.helpText }}</p>
</div>
</div>
<div class="text-area-field" v-show="field.inputType == 'text-area'">
<label class="control-label" :for="section.name">@{{ field.label }}</label>
<div class="controls">
<textarea :v-bind="field.data.content" class="input xlarge form-control" :placeholder="field.placeholder">
@{{ field.data.content }}
</textarea>
</div>
</div>
<div class="text-area-field" v-show="field.inputType == 'data-map'">
<label class="control-label" :for="section.name">@{{ field.label }}</label>
<div class="controls">
<textarea :v-bind="field.data.content" class="input xlarge form-control" :placeholder="field.placeholder">
@{{ field.data.content }}
</textarea>
</div>
</div>
</div>
</div>
<div class="control-group">
<div class="controls">
<div class="dropdown">
<a data-target="#" href="page.html" data-toggle="dropdown" class="dropdown-toggle">Dropdown <b class="caret"></b></a>
<ul class="dropdown-menu">
<li v-for="sectionType in sectionTypes">
<a @click="setSectionCreateType(sectionType)" href="#">@{{ sectionType.label }}</a>
</li>
</ul>
</div>
</div>
<div class="controls">
<div @click="addSection()" class="btn bdn-success" class="btn btn-success">Add Section</div>
<div @click="savePost()" class="btn bdn-success" class="btn btn-success">Save</div>
</div>
</div>
</fieldset>
{{Form::close()}}
Vuefile
<script type="text/javascript">
import Vue from 'vue';
import FormField from './create/FormField.vue';
export default {
components: {
FormField,
},
ready: function () {
},
filters: {},
data(){
return {
messages: [],
sections: [],
saveSections: [],
sectionCreateType: false,
sectionTypes: [
{
label: 'Company',
map: 'company',
fields: [
{
label: 'name',
name: 'name',
inputType: 'text',
placeholder: 'Company Name',
data: {
content: '',
},
},
{
label: 'symbol',
name: 'symbol',
inputType: 'text',
placeholder: 'stock symbol',
data: {
content: '',
},
}
]
},
{
label: 'Link',
map: 'link',
inputType: 'text',
data: {},
fields: [
{
label: 'url',
name: 'url',
inputType: 'text',
placeholder: 'Url',
data: {
content: '',
},
},
]
},
{
label: 'Paragraph',
map: 'paragraph',
data: {},
fields: [
{
label: 'content',
name: 'content',
inputType: 'text-area',
placeholder: 'Content',
data: {
content: '',
},
},
]
},
{
label: 'Person',
map: 'person',
data: {},
inputType: 'data-map',
'fields': [
{
label: 'first_name',
name: 'name',
placeholder: 'Person Name',
data: {
content: '',
},
},
{
label: 'last_name',
name: 'name',
placeholder: 'Person Name',
data: {
content: '',
},
}
]
},
],
}
},
directives: {},
events: {},
methods: {
setSectionCreateType(type)
{
console.log('setting sectionCreateType: ' + type.label)
this.sectionCreateType = type;
},
addSection()
{
if (!this.sectionCreateType) {
this.sectionCreateType = this.sectionTypes[0];
}
this.createSection(this.sectionCreateType);
},
createSection(type)
{
this.sections.push(Vue.util.extend({}, type))
},
previewPost(){
},
savePost: function(){
var view = this;
var saveObject = [];
var sectionObject = [];
this.sections.forEach(function (section) {
if(!sectionObject[section.type.map])
{
sectionObject[section.type.map] = [];
}
for (var key in section.type.fields) {
var field = section.type.fields[key];
var saveKey = [];
saveKey[field.name] = field.data.content;
}
sectionObject[section.type.map].push(saveKey);
});
saveObject.push(sectionObject);
console.log(saveObject);
},
}
}
</script>
1 ответ
Вы используете тот же v-model
поэтому VueJS делает то, что должен делать. Вы должны создать, например, список моделей и как-то обрабатывать index
(например, взять его с v-for
для каждого раздела / подраздела и использования v-model='list[index].field