在AJAX Promise之后,VueJS Component DOM没有更新

时间:2017-06-23 13:11:48

标签: javascript ajax dom promise vue.js

我知道在AJAX回调之后更新Vue应用程序中的数据的常见问题 - 我已经阅读了common gotchas并在过去使用Vue.set解决了类似的问题,但它不是今天为我工作。

我能想到的唯一区别是我在组件(.vue文件)中调用服务

如果我使用chrome中的VueJS工具检查dom,我可以看到服务中的数据被分配给我的module.options属性,这一切都发生在创建的函数中,但它没有在屏幕上绘制

附件是完整的.vue组件和屏幕截图,显示开发工具中记录的数据以及未呈现它的模板。

该片段不会运行,只是比将其直接粘贴到帖子中更好的格式。

简而言之,来自this.build_service.getOptionsForModule的回复正在给我我想要的内容,Vue.set( this.module, 'options', res.options )似乎可以正常运行,但不会更新DOM。

任何想法为什么?

<template>
	<div class="panel">
        <div class="panel-heading">
            <h2 class="panel-title">
                <a data-toggle="collapse" :href="'#collapse' + module.field" :data-parent="'#' + group_name" >
                    {{module.title}}
                    <!-- <span class="pull-right" v-if="module.options.length"> -->
                        [{{module.options.length}}]
                    <!-- </span> -->
                </a>
            </h2>
        </div>
        <div :id="'collapse' + module.field" class="panel-collapse collapse">
            <div class="panel-body">
                <div class="form-group">
                    {{module}}
                    
                    <!-- v-model="modules.selected[ module.field ]" -->

                    <select id="" data-target="#" class="form-control" :disabled="!module.is_active">
                        <option :value="{}">Select {{module.title}}...</option>
                        <option v-for="option in module.options" :value="option" v-html="option.name">
                        </option>
                    </select>
                    
                    <!-- @change="modules.checkChildren( module )" -->
                    
                </div>
                <div class="form-group">
                    <button class="btn btn-success mediumButton" @click="create( module )">
                        Create
                    </button>
                    
                    <!-- :disabled="!modules.isSelected( module.field )" -->

                    <button class="btn btn-primary mediumButton" @click="edit( module )">
                        Edit
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>
</template>


<script>

    import { EventBus } from '../event-bus.js';
    var BuildService = require('../services/build-service');

    export default {
        name: 'module',
        props: [ 'group_name', 'module' ],
        data: function() {
            return {
            	
            }
        },
        created: function() {
            console.log('single module component created');

            this.build_service = new BuildService();

            console.log( this.module );

            // if there are no options, load from service
            if( !this.module.options.length && this.module.parent === '' ) {

                this.build_service.getOptionsForModule( this.module )
                    .then(( res ) => {

                        if( res.length ) {
                            res = res[ 0 ];

                            Vue.delete( 
                                this.module,
                                'options'
                            );

                            Vue.set( 
                                this.module,
                                'options', 
                                res.options
                            );

                        } else {
                            console.error('no options found');
                            // TODO: status alert
                        }
                    })
                    .catch(function(err){
                        console.error(err);
                    });
            }
        },
        methods: {
            create: function( module ) {
                console.log('creating record for', module);
            },
            edit: function( module ) {
                console.log('editing', module);
            }
        }
    }

</script>

vuejs app and dev tools inspection

1 个答案:

答案 0 :(得分:3)

通常我会在发布后的几分钟内回答我自己的问题,但将来可能对其他人有用。

我试图修改从父组件传递下来的道具并且你不能从孩子那里做到这一点(好吧,不是没有将事件发送到高位以改变它以便数据可以流下来)

我需要将支柱的副本复制到数据结构中(有人评论说我没有在数据结构中注册模块,所以他们对此是正确的)

我在文档中找到了一个清晰的解决方案(RTFM !!)

  

单向数据流

     

所有道具在子属性和父属性之间形成单向向下的绑定

     

...

     

通常有两种情况可能会使支柱变异:   1. prop仅用于传递初始值,子组件只是想在之后将其用作本地数据属性;

     

...

     

这些用例的正确答案是:

     

定义使用prop的初始值作为其初始值的本地数据属性:

props: ['initialCounter'],
data: function () {
    return { counter: this.initialCounter }
}

https://vuejs.org/v2/guide/components.html#One-Way-Data-Flow