从选项循环

时间:2018-02-28 09:09:20

标签: vue.js vuejs2

我试图找到一种方法来绑定Vue select-element中的对象数组。案件有点如下:

data: {
  ideas: [
    { id: 1, code: "01A", text: "option 1", props: [] }, 
    { id: 2, code: "02A", text: "option 2 , props: [{ details: "something" }]}
  ]},
  currentForm: {
    something: "foo",
    else: "bar",
    ideaCode: "01A",
    text: "option 1"
  }
];

...并在HTML中......

<select v-model="currentForm.ideaCode" @change="setCodeAndLabelForForm(???)">
  <option v-for="i in ideas" value="i">{{ i.text }}<option>
</select>

基本上我需要能够跟踪哪个对象用户选择,触发我自己的更改事件,同时使用来自另一个对象的单个键绑定...选择的值/引用 - key应与用户选择的选项/对象分开。 注意:currentForm与选项的对象类型不同!它只包含一些选项恰好具有的属性,并且我试图通过触发用户选择的更改事件来转移到选项。

问题是我还没弄清楚如何传递当前为函数选择的值或者如何编写类似的东西:

<select v-model="selectedIdea" @change="setCodeAndLabelForForm" :track-by="currentForm.ideaCode">
  <option v-for="i in ideas" value="i">{{ i.text }}<option>
</select>

一种可能的(和工作)方法是:

<select v-model="currentForm.ideaCode" @change="setCodeAndLabelForForm">
  <option v-for="i in ideas" value="i.ideaCode">{{ i.text }}<option>
</select>

setCodeAndLabelForForm: function() {
    var me = this;
    this.ideas.forEach(function(i) {
        if(i.ideaCode == me.currentForm.ideaCode) {
            me.currentForm.ideaCode = i.selectedIdea.ideaCode;
            me.currentForm.text = i.text;
            ... do stuff & run callbacks ...
        }
    });
}

......但它看起来很糟糕。还有更好的建议吗?

6 个答案:

答案 0 :(得分:1)

你可以这样实现:

创建空对象数据以跟踪所选值:

currentForm: {}

在模型上观察currentForm并传递所选对象:

<select v-model="currentForm" @change="setCodeAndLabelForForm(currentForm)">

传递option中的选定值:(您在此步骤中做得很好,但我刚刚将i更改为idea,因为它有点令人困惑的循环索引)

<option v-for="idea in ideas" :value="idea">{{ idea.text }}<option>

应用您的方法:

setCodeAndLabelForForm(selected) {
  // Now, you have the user selected object
}

答案 1 :(得分:0)

我不知道这是否是最佳解决方案,但我使用这样的计算属性解决了这个问题:

在JavaScript文件(ES6)中:

data () {
    return {
        options: [
            { id: 1, text: "option 1" },
            { id: 2, text: "option 2" }
        ],
        selectedOptionId: 1
    }
},
computed: {
    selectedOption () {
        return _.find(this.options, (option) => {
            return option.id === this.selectedOptionId
        });
    }
}

在HTML文件中:

<select v-model="selectedOptionId">
  <option v-for="option in options" :value="option.id" :key="option.id">{{ option.text }}<option>
</select>

&#39; _&#39; symbol是一个名为Lodash的常见JavaScript库,我强烈推荐使用它。它可以让你节省宝贵的时间。

答案 2 :(得分:0)

如果您知道option仅来自v-for="i in ideas",那么<option>索引将与item索引相同。

因此<select>.selectedIndex将是所选this.item的索引。

new Vue({
  el: '#app',
  data: {
    ideas: [
      { id: 1, code: "01A", text: "option 1", props: [] }, 
      { id: 2, code: "02A", text: "option 2" , props: [{ details: "something" }]}
    ],
    currentForm: {ideaCode: "01A", text: "option 1"}
  },
  methods: {
    setCodeAndLabelForForm: function(selectedIndex) {
      var selectedIdea = this.ideas[selectedIndex];
      this.currentForm = {ideaCode: selectedIdea.code, text: selectedIdea.text};
    }
  }
})
<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>

<div id="app">
  <select v-model="currentForm.ideaCode" @change="setCodeAndLabelForForm($event.target.selectedIndex)">
    <option v-for="i in ideas" :value="i.code">{{ i.text }}</option>
  </select>
  <br> currentForm: {{ currentForm }}
</div>

与您的不同之处:@change="setCodeAndLabelForForm($event.target.selectedIndex)"setCodeAndLabelForForm实施。

答案 3 :(得分:0)

更好的解决方法:在v-for中使用索引

<select v-model="selIdeaIndex" @change="setCodeAndLabelForForm">
  <option v-for="(i,idx) in ideas" value="idx">{{ i.text }}<option>
</select>

对于js:

data: {
  selIdeaIndex:null,
  ideas: [
    { id: 1, code: "01A", text: "option 1", props: [] }, 
    { id: 2, code: "02A", text: "option 2 , props: [{ details: "something" }]}
  ]
},
methods:{
    setCodeAndLabelForForm: function() {
        var selIdea = this.ideas(this.selIdeaIndex);
        //Do whatever you wanna do with this selIdea.
    }
}

答案 4 :(得分:0)

一种谦虚的方法是使用$ref

有一种使用$ref@change的解决方案。

Vue.js get selected options' raw object

答案 5 :(得分:0)

自从我问这个问题已经有一段时间了,并且有很好的建议来处理这种情况。我不记得这里介绍的确切业务案例,但是快速浏览一下似乎无法弄清之后如何设置/初始化正确的选择,因为仅处理@change事件是孩子的玩法-这是配对一个单一值与基于对象的选项列表比较难。我最可能要寻找的是AngularJS曾经拥有的东西(逐项跟踪属性,该属性将任何给定值与selected-option相匹配)。

如今,我个人将UI逻辑分开,而不是试图迫使它们融合在一起。对我自己而言,最可行的方法是将选项列表和所选选项作为一个逻辑区域(即数据:{列表:[... options],selectedIdea:Object}),并将“ currentForm”-选择对象。让我们来看看:

  • selectedIdea是需要触发对currentForm对象的更改的东西。它不是任何一种混合模型,它只是一个普通的对象,纯净和简单的可用选择之一。
  • ...并再次:每当selectedValue ===选项之一时,select-下拉列表将自动设置为右选。
  • “ currentForm”对象具有可用于设置selectedIdea的属性。在这种情况下,它就是“ ideaCode”。此ideaCode不会自动进行任何配对,也不需要这样的 Component逻辑 来表示规则,从而触发选择与“ ideaCode”匹配的正确选项。
  • 不过,selectedIdea和currentForm-object是两个不同的逻辑元素。如果愿意的话,甚至可以将它们分离为不同的组件,在某些情况下,将'em分开确实是一件好事。

因此,通过这些语句,我想我将选择的v模型更改为应该的样子:所选对象之一(将v-model =“ currentForm.ideaCode”更改为v-model =“ selectedIdea”等)。然后,我只需为该selectedIdea添加观察者,然后从那里对currentForm-object进行任何更改。

如何通过currentForm.ideaCode初始化该选项?在创建方法上执行以下操作之一:

  • 迭代可用选项列表。当您找到其中currentForm.ideaCode == option.code => this.selectedIdea = option
  • 的选项时
  • ...或使用ecmascript find-method进行同样的操作
  • ...或使用下划线/破折号查找方法进行相同操作

另一种方法是使用计算值,如建议的Augusto Escobar。正如feng zhang所建议的那样,$ ref也可以工作,但是这种方法仍然需要解决方案,以便在以后初始化正确的选项(使用初始值加载编辑器时)。还要感谢Bhojendra Rauniyar -一直以来您都是对的,但是我无法理解答案,因为我无法弄清楚如何回溯初始选择。

感谢一年中的所有建议!