привязать выпадающий список Kendo vue к массиву объектов - PullRequest
1 голос
/ 31 марта 2019

ОБРАЗЕЦ https://stackblitz.com/edit/usjgwp?file=index.html

Я хочу показать количество кендо dropdownlist на странице. Точное число зависит от вызова API. Этот вызов API даст мне массив заинтересованных сторон. Заинтересованные стороны имеют следующие свойства: идентификатор, имя, тип, роль и isSelected.

Число dropdownlist, которое должно отображаться на этой странице, должно быть равно количеству уникальных type значений в массиве ответов API. то есть, numberOfDropdowns = stakeholders.map(a => a.type).distinct().count().

Теперь у каждого выпадающего списка будет datasource на основе свойства type. т. е. для раскрывающегося списка type = 1 источник данных будет stakeholders.filter(s => s.type == 1).

Также значения по умолчанию в раскрывающихся списках будут основаны на свойстве isSelected. Для каждого type только один объект будет иметь isSelected = true.

Я достиг этого, используя следующий код:

<template>
  <div
    v-if="selectedStakeholders.length > 0"
    v-for="(stakeholderLabel, index) in stakeholderLabels"
    :key="stakeholderLabel.Key"
  >
    <label>{{ stakeholderLabel.Value }}:</label>
    <kendo-dropdownlist
      v-model="selectedStakeholders[index].Id"
      :data-source="stakeholders.filter(s => s.type == stakeholderLabel.Key)"
      data-text-field="name"
      data-value-field="Id"
    ></kendo-dropdownlist>

    <button @click="updateStakeholders">Update form</button>
  </div>
</template>

<script>
import STAKEHOLDER_SERVICE from "somePath";
export default {
  name: "someName",
  props: {
    value1: String,
    value2: String,    
  },
  data() {
    return {
      payload: {
        value1: this.value1,
        value2: this.value2
      },
      stakeholders: [],
      selectedStakeholders: [],
      stakeholderLabels: [] // [{Key: 1, Value: "Stakeholder1"}, {Key: 2, Value: "Stakeholder2"}, ... ]
    };
  },
  mounted: async function() {
    await this.setStakeholderLabels();
    await this.setStakeholderDataSource();
    this.setSelectedStakeholdersArray();
  },
  methods: {   
    async setStakeholderLabels() {
      let kvPairs = await STAKEHOLDER_SERVICE.getStakeholderLabels();
      kvPairs = kvPairs.sort((kv1, kv2) => (kv1.Key > kv2.Key ? 1 : -1));
      kvPairs.forEach(kvPair => this.stakeholderLabels.push(kvPair));
        },
    async setStakeholderDataSource() {
      this.stakeholders = await STAKEHOLDER_SERVICE.getStakeholders(
        this.payload
      );
    }
    setSelectedStakeholdersArray() {
      const selectedStakeholders = this.stakeholders
        .filter(s => s.isSelected === true)
                .sort((s1, s2) => (s1.type > s2.type ? 1 : -1));

      selectedStakeholders.forEach(selectedStakeholder =>
        this.selectedStakeholders.push(selectedStakeholder)
      );      
    },
    async updateStakeholders() {
      console.log(this.selectedStakeholders);
    }
  }
};
</script>

Проблема в том, что я не могу изменить выбор в dropdownlist, выбор всегда остается таким же, как выбранные значения по умолчанию. Даже если я выберу другую опцию в любом dropdownlist, выбор фактически не изменится.

Я также пробовал связывать вот так:

<kendo-dropdownlist
      v-model="selectedStakeholders[index]"
            value-primitive="false"
      :data-source="stakeholders.filter(s => s.type == stakeholderLabel.Key)"
      data-text-field="name"
      data-value-field="Id"
    ></kendo-dropdownlist>

Если я выполняю привязку таким образом, я могу изменить выбор, но тогда выбор по умолчанию не происходит, первый вариант всегда является вариантом выбора, т.е. выбор по умолчанию не основан на свойстве isSelected.

Мое требование состоит в том, чтобы я показал dropdown с некоторыми вариантами выбора по умолчанию, разрешил пользователю выбирать различные параметры во всех различных раскрывающихся списках, а затем извлекать все варианты выбора, после чего нажималась кнопка обновления.

UPDATE : Когда я использую первый метод для привязки, свойство Id объектов в массиве selectedStakeholders фактически изменяется, но оно не отражается на пользовательском интерфейсе, т. Е. На пользовательском интерфейсе выбранный параметр всегда является параметром по умолчанию, даже если когда пользователь меняет выбор. Также, когда я подписываюсь на события change и select, я вижу, что срабатывает только событие select, событие change никогда не срабатывает.

1 Ответ

0 голосов
/ 01 апреля 2019

Получается, что это было ограничение Vue.js (или ограничение JS, которое унаследовано vue), Ссылка

Мне пришлось явно изменить значения в массиве selectedStakeholders следующим образом:

<template>
  <div
    v-if="selectedStakeholders.length > 0"
    v-for="(stakeholderLabel, index) in stakeholderLabels"
    :key="stakeholderLabel.Key"
  >
    <label>{{ stakeholderLabel.Value }}:</label>
    <kendo-dropdownlist
      v-model="selectedStakeholders[index].Id"
      :data-source="stakeholders.filter(s => s.type == stakeholderLabel.Key)"
      data-text-field="name"
      data-value-field="Id"
      @select="selected"
    ></kendo-dropdownlist>

    <button @click="updateStakeholders">Update form</button>
  </div>
</template>

И в методах:

selected(e) {
      const stakeholderTypeId = e.dataItem.type;
      const selectedStakeholderIndexForTypeId = this.selectedStakeholders.findIndex(
        s => s.type == stakeholderTypeId
      );
      this.$set(
        this.selectedStakeholders,
        selectedStakeholderIndexForTypeId,
        e.dataItem
      );
    }
...