2017-01-27 44 views
2

我有一个web应用程序,其中接口基于vue.js 2.0。如何从vue.js中的另一个组件更新一个组件

我有基于select2插件显示输入的组件。

默认情况下,它显示选定的选项,但当用户点击它时,我会显示select2以允许用户修改选项。

代码如下所示:

<template> 
<div @click="toggleEdit"> 
    <span v-show="isEnabled"> 
     <select 
      class="form-control" 
      :name="name" 
      :multiple="multiple" 
     > 
      <option v-for="opt in options" :value="opt.id"> {{ opt.text }} </option> 
     </select> 
    </span> 
    <span v-show="!isEnabled"> 
     <div v-if="selectedOptions.length === 0"> 
      {{ emptyText }} 
     </div> 
     <div v-for="opt in selectedOptions"> 
      {{ opt }} 
     </div> 
    </span> 
</div> 
</template> 
<script> 
export default { 
    props: { 
     options: { 
      type: Array, 
      required: false, 
      default: function() { 
       return [] 
      } 
     }, 
     name: { 
      required: true, 
      type: String 
     }, 
     multiple: { 
      required: false, 
      type: Boolean, 
      default: false 
     }, 
     emptyText: { 
      required: false, 
      type: String, 
      default: "" 
     }, 
     sourceUrl: { 
      required: false, 
      type: String, 
      default: "" 
     }, 
     enabled: { 
      required: false, 
      type: Boolean, 
      default: false 
     } 
    }, 

    data() { 
     return { 
      isEnabled: this.enabled 
     } 
    }, 

    watch: { 
     options: { 
      handler: function() { 
       console.log(arguments) 
      }, 
      deep: true 
     } 
    }, 

    mounted: function() { 
     this.select = $(this.$el).find("select"); 
     this.select.select2(); 
     var that = this; 
     this.select.on("change", function(e) { 
      var indexMap = {}; 
      for(var i = 0; i < that.options.length; i++) { 
       that.options[i].selected = false; 
       indexMap[that.options[i].id] = i; 
      } 
      var selected = that.select.select2('val'); 
      if(typeof selected === "string") { 
       selected = [selected]; 
      } 
      for(var i = 0; i < selected.length; i++) { 
       var index = indexMap[selected[i]]; 
       console.log(index) 
       console.log(selected[i]) 
       if(index !== undefined) { 
        var option = that.options[index]; 
        option.selected = true; 
        that.$set(that.options, index, option); 
       } 
      } 
     }) 
     this.select.on("select2:open", function() { 
      that.isEnabled = true; 
     }); 
     this.select.on("select2:close", function() { 
      that.isEnabled = false; 
     }); 
    }, 
    methods: { 
     toggleEdit() { 
      if(this.isEnabled) return; // to pass select2 clicks 
      this.isEnabled = !this.isEnabled; 
      var that = this; 
      this.$nextTick(function() { 
       that.select.select2("open"); 
      }); 
     } 
    }, 
    computed: { 
     selectedOptions: function() { 
      console.log(this.options) 
      return this.options.filter(function(option) { 
       console.log(option.selected); 
       if(option.selected === true) return true; 
       return false; 
      }); 
     } 
    } 
} 

的问题是:我想要显示多个不同的selects使用该组件。名称属性可以是以下之一:model1[field1],model1[field2],...,model40[field1],...,model99[field15],其中每个模型N对应于数据库中具有其各自字段的表。

当用户改变选项,AJAX请求必须被发送到服务器,它返回JSON对象像这样

{ 
    "errorText": null or "text with error", 
    "disableFields": ["model3[field4]", "model24[field15]"] 
} 

我想分析“disableFields”阵列和从this组分another组件禁用。做到这一点(伪代码)

方式一:

foreach field in disableField: 
    $(document).trigger("disableField" + field); 

而且在this组件

var self = this; 
$(document).on("disableField" + this.name, function() { 
    self.isEnabled = false 
}) 

是否有更好的方法来做到这一点没有父组件的mounted方法?

+0

对未来,尽量做到短。你的问题质量好,但太长了... –

回答

5

不允许直接与其他组件通信。您可以使用父组件在组件或some kind of event bus之间进行通信。

var bus = Vue() 

组件A发出一个事件,而组件B可以捕获它,反之亦然。

// component A 
bus.$emit('cool_event_name', interesting_data) 

// component B 
bus.$on('cool_event_name', function(interesting_data) { 
    console.log(interesting_data) 
}) 
0

因为你的帖子太长,而且有太多东西在那里,所以要真正得到你想要达到的东西并不容易,但我会尝试。如果缺少某些内容,只需发表评论,我会尝试编辑以更好地帮助您。

禁用FIELDS

我建议有此数组中父data您的组件(例如,具有全格式/网页组件),然后把它传递给你的领域,如<component-instance :disabled='disabled.componentId'>请注意:disabled。它是数据绑定将保持这种同步单向与父数据(这意味着你的父母disabled.componentId每一个变化都会在你的子组件中反映出来)

解析“已禁用” JSON

它在我看来相当直接,因为您只需将返回的字段分配给您的data: { disabled },但如果您无法弄清楚 - 请告诉我们。组件**

之间的通信

**其他方式。如果你想从子组件更新父,你必须使用或者使用Vue的事件总线或事件处理的事件。 儿童组件,您可以用<child-component @click='yourParentMethod()'>如果从子组件的子组件通过特殊的数据,或者创建自定义事件emiters像它不是必需的:

// child component 
methods: { 
someMethod() => { 
this.emit('customEvent', someData) 
} 
} 

//parent component 
<child-component @customEvent='customEventHandler(dataFromChild)'> 

希望它能帮助。

3

您可以使用this.$root没有全局变量:

// component A emits an event 
export default { 
    name: 'A', 
    methods: { 
    buttonClicked: function() { 
     this.$root.$emit('myEvent', 'new message!'); 
    } 
    } 

// component B catch your event 
export default { 
    name: 'B', 
    data() { 
    return { 
     message: 'Old message!' 
    } 
    }, 
    mounted: function() { 
    this.$root.$on('myEvent', (text) => { // here you need to use the arrow function 
    this.message = text; 
    }) 
    } 
} 
相关问题