Цикл Vue v-for - Как настроить таргетинг на компонент при фильтрации массива - PullRequest
0 голосов
/ 28 ноября 2018

Я использую вычисленное значение для динамической фильтрации массива («заказы»).

Вычисленная функция .filter() позволяет пользователю динамически выполнять поиск по номеру заказа, названию или справочнику:

data() {
  return {
    orders: [],
    search: ""  // search string from a text input    
  };
},

computed: {
  filtered: 
    return this.orders.filter(order => {
      const s =
        order.order_number + order.reference + order.name;
      const su = s.toUpperCase();
      return su.match(this.search.toUpperCase());
    });
  }

Я использую цикл v-for для отображения результатов поиска следующим образом.:

 <tbody v-for="(order, index) in filtered" :key="order.id">              
   <tr>       
     <td @click="add_events(order, index)>{{order.order_number}}</td>
     <td>{{order.reference}}</td>
     <td>{{order.name}}</td>
      ...
    </tr>
  </tbody>

Я хочу использовать @click для нацеливания на конкретный компонент (объект) в фильтруемом массиве и использовать $set для добавления значения ("objEvents") к этому объекту:

methods: {
  add_events (order, index) {
    const objEvents= [ external data from an API ]      
    this.$set(this.orders[index], "events", objEvents)          
  }
}

Однако index компонента в массиве отфильтрованный («отфильтрованный») не совпадает с его index в массиве original ("orders") и поэтому метод add_events нацелен на неправильный компонент.

Можно ли использовать key для нацеливания на правильный компонент?или есть какой-то другой способ идентифицировать целевой компонент в фильтрованном массиве?

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Нет необходимости отслеживать index.filtered - это просто массив ссылок на исходные объекты в orders, поэтому вы можете изменить итератор order в add_events() для достижения желаемого эффекта:

this.$set(order, 'events', objEvents);

new Vue({
  el: '#app',
  data() {
    return {
      orders: [
        {id: 1, order_number: 111, name: 'John', reference: 'R111'},
        {id: 2, order_number: 222, name: 'Bob', reference: 'R222'},
        {id: 3, order_number: 333, name: 'Bob', reference: 'R333'},
      ],
      search: ''
    };
  },
  computed: {
    filtered() {
      return this.orders.filter(order => {
        const s =
              order.order_number + order.reference + order.name;
        const su = s.toUpperCase();
        return su.match(this.search.toUpperCase());
      });
    }
  },
  methods: {
    add_events(order, index) {
      const objEvents = [
        {id: 1, name: 'Event 1'},
        {id: 2, name: 'Event 2'},
        {id: 3, name: 'Event 3'}
      ];
      this.$set(order, "events", objEvents);
    }
  }
})



  
  
                  
      
        {{order.order_number}}
        {{order.reference}}
        {{order.name}}
        {{order.events}}
      
    
  
  
  {{orders}}
0 голосов
/ 28 ноября 2018

Вы можете отобразить исходный массив и добавить свойство origIndex к каждому элементу следующим образом:

    computed:{
        filtered(){
           let mapped= this.orders.map((item,i)=>{
                             let tmp=item;
                              tmp.origIndex=i;
                             return tmp;
                            });
             return this.mapped.filter(order => {
                    const s =
                      order.order_number + order.reference + order.name;
                       const su = s.toUpperCase();
                    return su.match(this.search.toUpperCase());
             });
            }
        }//end computed

В своем шаблоне используйте свойство origIndex вместо index

           <tbody v-for="(order, index) in filtered" :key="order.id">              
              <tr>       
                <td @click="add_events(order, order.origIndex)>{{order.order_number}}</td>
               <td>{{order.reference}}</td>
                <td>{{order.name}}</td>
                 ...
               </tr>
            </tbody>
...