【问题标题】:Vue.js DOM not updating (integrating a Symfony form with dynamic content)Vue.js DOM 未更新(将 Symfony 表单与动态内容集成)
【发布时间】:2018-11-14 02:45:44
【问题描述】:

我创建了一个动态vue component,它使用Symfony/Twig 加载整个表单生成的后端。这适用于简单的表格。

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

我被困在最后一步。我得到了更新字段的 html,我用这个新对象替换了 cities 输入,但更改没有显示在 DOM 中

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

我在mounted()updated() 中都调用了这个方法。

编辑问题已解决:我在 ajax 回调中调用组件的道具,而不是事先将其内容存储到变量中。

<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>

【问题讨论】:

    标签: jquery vue.js


    【解决方案1】:

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

    注意,内容是作为纯 HTML 插入的 - 它们不会被编译为 Vue 模板

    换句话说,由于您使用v-html 加载后端生成的表单,因此它不用作 Vue 模板,它只是作为纯 HTML 粘贴,这意味着它无法绑定到值并以您通常在 Vue 应用程序中的方式更新内容。

    【讨论】:

    • 感谢您的回答。我知道这不是推荐的“Vue 方式”,但你知道我如何强制刷新 DOM 吗?
    • $forceUpdate() 是一个强制更新 Vue DOM 的函数,但同样v-html 不会将事物绑定到 Vue。我认为您需要考虑使用 Vue.compile("template as string") vuejs.org/v2/api/#Vue-compile
    猜你喜欢
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多