Как я могу отфильтровать цикл VueJS, используя флажки для отображения разных результатов? - PullRequest
0 голосов
/ 04 мая 2019

У меня проблемы с применением фильтров при использовании флажков в списке результатов, и мне нужна помощь.

В настоящее время только опция «Все», кажется, применяет любую логику фильтрации.

Мой HTML, содержащий мои фильтры и цикл, выглядит следующим образом:

<div class="container" id="clubs">
    <div class="filter">
        <label><input type="checkbox" v-model="selectedCategory" value="All" /> All</label>
        <label><input type="checkbox" v-model="selectedCategory" value="Parking" /> Parking</label>
        <label><input type="checkbox" v-model="selectedCategory" value="Toilets" /> Toilets</label>
        <label><input type="checkbox" v-model="selectedCategory" value="Floodlights" /> Floodlights</label>
    </div>

    <ul class="clubs-list">
        <li v-for="club in filteredClubs">{{ club.clubName }}</li>
    </ul>
</div> 

Тогда код внутри моего приложения VueJS выглядит следующим образом:

var vm = new Vue({
    el:  "#clubs",
    data: {
        clubs: [
            { clubName: "Club One", clubParking: true, clubToilets: false, clubFloodlights: true },
            { clubName: "Club Two", clubParking: true, clubToilets: false, clubFloodlights: false },
            { clubName: "Club Three", clubParking: false, clubToilets: true, clubFloodlights: true },
        ],
        selectedCategory: "All"
    },
    computed: {
        filteredClubs: function() {
            var vm = this;
            var category = vm.selectedCategory;

            if(category === "All") {
                return vm.clubs;
            } else {
                return vm.clubs.filter(function(club) {
                    return club.clubParking === category;
                });
            }
        }
    }
});

Любая помощь приветствуется, так как я застрял на несколько часов.

1 Ответ

1 голос
/ 04 мая 2019

Вам необходимо обновить фильтр, чтобы проверить категорию, а затем выполнить фильтрацию в поле.

return vm.clubs.filter(function(club) {
  switch(category){
     case 'Toilets':
      return club.clubToilets;
     case 'Parking':
      return club.clubParking;
     // etc...
  }
});

Вы можете немного изменить его, задав имя поля.

return vm.clubs.filter(function(club) {
  let fname;
  switch(category){
     case 'Toilets':
      fname ='clubToilets';
     case 'Parking':
      fname = 'clubParking';
     // etc...
  }
  return club[fname]
});

Вы также можете просто использовать значение select как имя вашего поля и использовать его напрямую. Однако это может ограничить вас от дополнительной логики.

<label><input type="checkbox" v-model="selectedCategory" value="clubParking" /> Parking</label>
return vm.clubs.filter(function(club) {
  return club[category];
}

Суть в том, что категория должна быть сопоставлена ​​с именем поля в вашем объекте.

Для нескольких предметов:

// Map the field names depending on your checkbox values. `selectedCategory` should be an array.

const selectedFieldNames =  selectedCategory.map(category=>{
      switch(category){
         case 'Toilets':
          return 'clubToilets';
         case 'Parking':
          return 'clubParking';
         // etc...
      }
})

// selectedFieldNames now contains the names of your object fields

// This will now return all items that have all those fields set to 'true'
return vm.clubs.filter(function(club) {
  return selectedFieldNames.every(fname=>club[fname])
}

Рабочий пример, основанный на вашем опубликованном коде.

Примечание: для этого действительно может потребоваться некоторая очистка, но я оставил его в формате, в котором вы можете сравнить свои работы и наши.

var vm = new Vue({
	el: "#clubs",
	data: {
		clubs: [
			{
				clubName: "Club One",
				clubParking: true,
				clubToilets: false,
				clubFloodlights: true
			},
			{
				clubName: "Club Two",
				clubParking: true,
				clubToilets: false,
				clubFloodlights: false
			},
			{
				clubName: "Club Three",
				clubParking: false,
				clubToilets: true,
				clubFloodlights: true
			}
		],
		selectedCategory: []
	},
	computed: {
		filteredClubs: function() {
			var vm = this;
			var categories = vm.selectedCategory;
      
			if (categories.includes("All")) {
				return vm.clubs;
			} else {
				const selectedFieldNames = categories.map(category => {
					switch (category) {
						case "ClubToilets":
							return "clubToilets";
						case "ClubParking":
							return "clubParking";
						case "ClubFloodlights":
							return "clubFloodlights";
					}
				});

				return vm.clubs.filter(function(club) {
					return selectedFieldNames.every(fname=>club[fname])
				})			
			}
		}
	}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="container" id="clubs">
	<div class="filter">
		<label><input type="checkbox" v-model="selectedCategory" value="All" /> All</label>
		<label><input type="checkbox" v-model="selectedCategory" value="ClubParking" /> Parking</label>
		<label><input type="checkbox" v-model="selectedCategory" value="ClubToilets" /> Toilets</label>
		<label><input type="checkbox" v-model="selectedCategory" value="ClubFloodlights" /> Floodlights</label>
	</div>
	
	<ul class="clubs-list">
		<li v-for="club in filteredClubs">{{ club.clubName }}</li>
	</ul>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...