Vue.js DOM不更新(将Symfony表单与动态内容集成在一起)

时间:2018-11-14 02:45:45

标签: jquery vue.js

我做了一个动态的vue component,它加载了Symfony/Twig生成的整个表单。这可以通过简单的形式很好地工作。

现在,我正在尝试使其与动态字段(请说国家/城市)一起使用:当您选择 国家 在表单的输入之一中,ajax调用会更新 城市 '输入中的选择。

我被困在最后一步。我得到了更新字段的html,将 城市 输入替换为此新对象,但更改未显示在DOM中

下面是我组件的代码。在initializeDynamicFields()方法中(在代码底部),在成功进行ajax调用后,我进行了替换操作,该替换操作不会像希望的那样更新DOM。 dynamicFieldParentdynamicFieldChild是表单动态字段的ID。

我在mounted()updated()中都调用此方法。

  

已解决问题:我在ajax回调内部调用组件的prop,而不是将其内容预先存储在变量中。

<template>
    <div class="card bg-light border-dark">
        <div class="card-body">
            <h3 v-if="title" class="card-title">{{ title }}</h3>
            <div v-html="content" v-on:click.capture="handleClick"></div>
            <!--<div ref="body" v-on:click.capture="handleClick"></div>-->
        </div>
    </div>
</template>

<script type="text/babel">
    var formSerialize = require('form-serialize');
    export default {
        name: "dynamic-form",
        props: ['url', 'dynamicFieldParent', 'dynamicFieldChild'],
        data() {
            return {
                title: '',
                content: '',
                components: null
            };
        },
        created() {
            this.load(this.url);
        },
        mounted() {
            if (this.dynamicFieldParent) {
                this.initializeDynamicFields();
            }
        },
        updated() {
            if (this.dynamicFieldParent) {
                this.initializeDynamicFields();
            }
        },
        methods: {
            load(url) {
                axios.get(url, {
                    headers: {'X-Requested-With': 'XMLHttpRequest'}
                }).then(response => {
                    this.title = response.data.title;
                    this.content = response.data.content;
                    this.components = response.data.components;
                });
            },

            handleClick(e) {
                if (e.target.tagName == 'BUTTON' && e.target.type == 'submit' && e.target.form.checkValidity()) {
                    this.submit(e);
                }
            },

            submit(e) {
                e.preventDefault();
                this.$root.$emit('form-sending');
                let data = formSerialize(e.target.form, {
                    hash: false, empty: true
                });
                data += '&' + e.target.name + '=' 
                        + encodeURIComponent(e.target.value);
                axios.post(this.url, data, {
                    headers: {'X-Requested-With': 'XMLHttpRequest'}
                }).then(response => {
                    this.title = response.data.title;
                    this.content = response.data.content;
                    this.components = response.data.components;
                    if (response.status == 201) {
                        this.$root.$emit('form-success');
                    }
                });
            },

            initializeDynamicFields() {
                var $parent = $('#' + this.dynamicFieldParent);
                var $child = $('#' + this.dynamicFieldChild);
                $parent.change(function() {
                    var $form = $parent.closest('form');
                    var formData = new FormData();
                    formData.set($parent.attr('name'), $parent.val());
                    axios.post($form.attr('action'), formData).then(response => {
                        $child.replaceWith(
                            response.data.content.find('#' + this.dynamicFieldChild)
                        );

                    });
                });
            }
        }
    }
</script>

1 个答案:

答案 0 :(得分:0)

来自https://vuejs.org/v2/api/#v-html

请注意,内容以纯HTML格式插入-不会被编译为Vue模板

换句话说,由于您使用的是v-html来加载后端生成的表单,因此它不用作Vue模板,而是以纯HTML格式粘贴,这意味着它将无法绑定以通常在Vue应用中的方式来价值和更新事物。