嘿,我已经有一段时间了,我正尝试使用按钮按类别和关键字过滤模板。我有一个使用filter方法的vuejs应用程序。除非我没有选择任何关键字并开始选择多个类别,否则它的效果非常好。例如,我有一个名为test的模板,该模板与运动类别和假日类别相关联。当两个都被选中时,我得到一个副本。我在这方面真的很贴心,我现在只停留在此部分上大约一个星期了。我意识到这是很多代码,但是它干净,易读,除非我给您概述,否则是没有意义的。
在此处显示代码的小提琴 https://jsfiddle.net/rshba6jz/
这里有前端代码
<?php require_once('header.php');
require_once('database.php');
if ($result = $mysqli->query("SELECT t.*, GROUP_CONCAT(c.category) categories, GROUP_CONCAT(k.keyword) keywords FROM dataclayTemplates t LEFT JOIN dataclayCategoryLink cl JOIN dataclayCategories c ON cl.categoryId=c.id ON t.id=cl.templateId LEFT JOIN dataclayKeywordLink kl JOIN dataclayKeywords k ON kl.keywordId=k.id ON t.id=kl.templateId GROUP BY t.id"))
{
while($row = $result->fetch_array(MYSQLI_ASSOC)) {
if($row["categories"] == null) {
$row["categoryArray"] = [];
} else {
$row["categoryArray"] = array_unique(explode(",",$row["categories"]));
}
unset($row["categories"]);
if($row["keywords"] == null) {
$row["keywordArray"] = [];
} else {
$row["keywordArray"] = array_unique(explode(",",$row["keywords"]));
}
unset($row["keywords"]);
$templateArray[] = $row;
}
}
$result->close();
$categoryArray = array();
if ($result = $mysqli->query("SELECT category FROM dataclayCategories;"))
{
while($row = $result->fetch_array(MYSQLI_ASSOC)) {
array_push($categoryArray, $row['category']);
}
}
$result->close();
$keywordArray = array();
if ($result = $mysqli->query("SELECT keyword FROM dataclayKeywords;"))
{
while($row = $result->fetch_array(MYSQLI_ASSOC)) {
array_push($keywordArray, $row['keyword']);
}
}
$result->close();
$mysqli->close();
?>
<div v-cloak id="templates" class="container content">
<div class="col-lg-3 visible-lg-block hidden-md" id="SearchTemplatesLargeContainer">
<form role="form" role="form" onsubmit="return false">
<div class="form-group">
<label for="searchBar">Search</label>
<input v-model="searchQuery" type="text" placeholder="Search Tempates" id="searchBar" autocomplete="off" class="form-control">
</div>
<div class="form-group">
<label>Sort By</label>
<select v-model="sortBy" class="form-control">
<option value="renderTime">Render Time</option>
<option value="az">A-Z</option>
<option value="dateAdded">Newest</option>
</select>
</div>
<div class="form-group">
<h5>Categories</h5>
<div v-for="category in categories" :class="category + 'Button'" v-on:click.prevent="selectCategory(category)" class="btn btn-default categoryButton">
{{category}}
</div>
</div>
<div class="form-group">
<h5>Keywords</h5>
<div v-for="keyword in keywords" :class="keyword + 'Button'" v-on:click.prevent="selectKeyword(keyword)" class="btn btn-default categoryButton">
{{keyword}}
</div>
</div>
</form>
</div>
<!--end lg template menu col-lg-3-->
<!--search templates modal-->
<div class="modal fade" role="dialog" id="searchTemplatesModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">X</button>
<h2 class="modal-title">Search Templates</h2>
<!--end .modal-title-->
</div>
<!--end modal-header-->
<div class="modal-body">
<form role="form">
<div class="form-group">
<label>Search</label>
<input v-model="searchQuery" type="text" placeholder="Search Tempates" autocomplete="off" class="form-control">
</div>
<!--.end searchQuery-->
<div class="form-group">
<label>Sort By</label>
<select v-model="sortBy" class="form-control">
<option value="renderTime">Render Time</option>
<option value="az">A-Z</option>
<option value="dateAdded">Newest</option>
</select>
</div>
<!--end sortBy-->
<div class="form-group">
<h5>Categories</h5>
<div v-for="category in categories" :class="category + 'Button'" v-on:click.prevent="selectCategory(category)" class="btn btn-default categoryButton">
{{category}}
</div>
</div>
<!--end categorys-->
<div class="form-group">
<h5>Keywords</h5>
<div v-for="keyword in keywords" :class="keyword + 'Button'" v-on:click.prevent="selectKeyword(keyword)" class="btn btn-default categoryButton">
{{keyword}}
</div>
</div>
<!--end keywords-->
</form>
</div>
<!--end .modal-body-->
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-block" data-dismiss="modal">Search</button>
</div>
<!--end .modal-footer-->
</div>
<!--end .modal-content-->
</div>
<!--end .modal-dialog-->
</div>
<!-- end search templates modal-->
<div class="col-lg-9 col-md-12 col-sm-12 col-xs-12">
<div class="row">
<h1 class="mainHeading">Templates</h1>
</div>
<div class="row">
<div v-cloak v-bind:key="template.itemId + '_' + index" v-for="(template, index) in searchResults" class="col-md-4">
<div class="card">
<video muted :src="mysource" controls preload="none" controlsList="nodownload nofullscreen" :poster="mysouce" loop="loop"></video>
<div class="card-body">
<p class="card-title">{{template.itemName}}</p>
<!--end card-title-->
<p v-show="displayCount==0" class="card-text">Please create a display to customize</p>
<!--end user has no display card-text-->
<p v-show="displayCount>0" class="card-text">Custom Text, Custom Colors, Upload Logo</p>
<!--end user has display card text-->
<p class="card-text">{{template.renderTime}} minutes</p>
<a href="#" v-show="loggedIn==true && displayCount>0" class="btn btn-primary btn-block">Customize</a>
<!--logged in and has display button-->
<a href="#" v-show="loggedIn==false" class="btn btn-primary btn-block" disabled>Customize</a>
<!--not logged in button-->
<a href="profile.php?showAddDisplayForm=1" v-show="loggedIn==true && displayCount==0" class="btn btn-primary btn-block">Create A Display</a>
</div>
<!--end card-body-->
</div>
<!--end card-->
</div>
<!-- end col-md-4-->
</div>
<!--end row-->
</div>
<!--end col-lg-9 col-md-12 col-sm-12 col-xs-12-->
</div>
<!--end templates app-->
<script>
var app = new Vue({
el: '#templates',
data: {
loggedIn: false,
displayCount:'<?php if(isset($_SESSION['displayCount'])){echo $_SESSION['displayCount'];} else{echo 0;}?>',
searchQuery:'',
templateArray: <?php echo json_encode($templateArray); ?>,
filteredTemplateArray: <?php echo json_encode($templateArray); ?>,
categories: <?php echo json_encode($categoryArray); ?>,
selectedCategories: [],
keywords: <?php echo json_encode($keywordArray); ?>,
selectedKeywords: [],
sortBy: ''
},
computed: {
searchResults: function(){
return this.filteredTemplateArray.filter((template)=>{
return template.itemName.toLowerCase().includes(this.searchQuery.toLowerCase());
})
}
},
created: function() {
this.loggedIn=<?php if(isset($_SESSION['loggedIn'])){echo $_SESSION['loggedIn'];} else {echo 0;}?>;
this.filteredTemplateArray.sort(function(a,b) {
return parseInt(a.renderTime) - parseInt(b.renderTime);
});
},
watch: {
sortBy: function() {
if(this.sortBy == "az") {
this.filteredTemplateArray.sort(function(a,b) {
if(a.itemName > b.itemName) {
return 1;
}
if(a.itemName < b.itemName) {
return -1;
}
return 0;
});
}
if(this.sortBy == "dateAdded") {
this.filteredTemplateArray.sort(function(a,b) {
if(a.dateAdded < b.dateAdded) {
return 1;
}
if(a.dateAdded > b.dateAdded) {
return -1;
}
return 0;
});
}
if(this.sortBy == "renderTime") {
this.filteredTemplateArray.sort(function(a,b) {
return parseInt(a.renderTime) - parseInt(b.renderTime);
});
}
}
},
mounted: function(){
this.sortBy="renderTime";
},
methods: {
filter: function() {
var filteredCategoryArray = [];
var filteredKeywordArray = [];
if(this.selectedCategories.length != 0) {
for(var i = 0; i < this.templateArray.length; i++) {
for(var j = 0; j < this.selectedCategories.length; j++ ) {
for(var k = 0; k < this.templateArray[i].categoryArray.length; k++ ) {
if(this.templateArray[i].categoryArray[k] == this.selectedCategories[j]) {
console.log(this.templateArray[i].categoryArray[k]);
console.log(this.selectedCategories[j]);
var arrayDuplicate = false;
for(var l = 0; l < filteredKeywordArray.length; l++) {
if(filteredCategoryArray[l].id == this.templateArray[i].id) {
arrayDuplicate = true;
}
}
if(arrayDuplicate == false) {
filteredCategoryArray.push(this.templateArray[i]);
}
}
}
}
}
} else {
for(var i = 0; i < this.templateArray.length; i++){
filteredCategoryArray.push(this.templateArray[i]);
}
}
if(this.selectedKeywords.length != 0) {
for(var i = 0; i < filteredCategoryArray.length; i++) {
for(var j = 0; j < this.selectedKeywords.length; j++ ) {
for(var k = 0; k < filteredCategoryArray[i].keywordArray.length; k++ ) {
if(filteredCategoryArray[i].keywordArray[k] == this.selectedKeywords[j]) {
var arrayDuplicate = false;
for(var l = 0; l < filteredKeywordArray.length; l++) {
if(filteredKeywordArray[l].id == filteredCategoryArray[i].id) {
arrayDuplicate = true;
}
}
if(arrayDuplicate == false) {
filteredKeywordArray.push(filteredCategoryArray[i]);
}
}
}
}
}
} else {
for(var i = 0; i < filteredCategoryArray.length; i++){
filteredKeywordArray.push(filteredCategoryArray[i]);
}
}
if(this.sortBy == "az") {
filteredKeywordArray.sort(function(a,b) {
if(a.itemName > b.itemName) {
return 1;
}
if(a.itemName < b.itemName) {
return -1;
}
return 0;
});
}
if(this.sortBy == "dateAdded") {
filteredKeywordArray.sort(function(a,b) {
if(a.dateAdded < b.dateAdded) {
return 1;
}
if(a.dateAdded > b.dateAdded) {
return -1;
}
return 0;
});
}
if(this.sortBy == "renderTime") {
filteredKeywordArray.sort(function(a,b) {
return parseInt(a.renderTime) - parseInt(b.renderTime);
});
}
this.filteredTemplateArray = filteredKeywordArray;
$('html,body').scrollTop(0);
},
selectCategory: function(category) {
var categoryButton = $('.' + category + 'Button');
categoryButton.toggleClass('categoryButtonSelected');
if(this.selectedCategories.includes(category)){
var array = [];
for(var i = 0; i < this.selectedCategories.length; i++) {
if(this.selectedCategories[i] != category) {
array.push(this.selectedCategories[i]);
}
}
this.selectedCategories = array;
} else {
this.selectedCategories.push(category);
}
this.filter();
},
selectKeyword: function(keyword) {
var categoryButton = $('.' + keyword + 'Button');
categoryButton.toggleClass('categoryButtonSelected');
if(this.selectedKeywords.includes(keyword)){
var array = [];
for(var i = 0; i < this.selectedKeywords.length; i++) {
if(this.selectedKeywords[i] != keyword) {
array.push(this.selectedKeywords[i]);
}
}
this.selectedKeywords = array;
} else {
this.selectedKeywords.push(keyword);
}
this.filter();
}
}
});
</script>
当模板被单击时,我得到的是在vue检查器中传递到我的filterTemplateTemplate中的内容。如果有多个具有相同ID的项目(在这种情况下,我希望将它们过滤掉223,那么就不会有重复项。它可以很好地使用关键字,但不能使用类别。我敢肯定它很简单,但我确实遇到了麻烦并提供了一些帮助会很棒。
filteredTemplateArray:Array[1]
0:Object
categoryArray:Array[3]
0:"Misc"
1:"Holiday"
2:"Sports"
dateAdded:"2018-10-01 17:54:22"
id:"233"
itemId:"fb41a01641bb2e769db412d3b21c2e3e"
itemName:"test"
keywordArray:Array[2]
0:"Snow"
1:"LensFlare"
projectPath:"M:/Projects/Generics/uploads/testLocation"
renderTime:"4"
stillImageLocation:"0.13"
tested:"0"
thumbName:"TEST"
答案 0 :(得分:0)
创建一个监视选定类别的监视程序,并在其更改时运行一种方法,该方法可以过滤出重复项,并在选定类别.length == 0时将过滤的类别设置回原始数组。这将创建一个向上计数的类别过滤器。例如,如果选中了运动和假期,它将仅显示运动中的所有项目和假日中的所有项目,这似乎比倒计时或显示仅在两者中都存在的项目更好。我使用app代替它作为变量,我将其称为vue实例,因为当您深入研究某个函数时,并不总是意味着该应用程序。
watch: {
selectedCategories(){
this.categoryFilter();
},
sortBy(){
this.sortTemplatesBy();
}
},
methods: {
sortTemplatesBy: function(){
if(this.sortBy == "az") {
this.filteredTemplateArray.sort(function(a,b) {
if(a.itemName > b.itemName) {
return 1;
}
if(a.itemName < b.itemName) {
return -1;
}
return 0;
});
}
if(this.sortBy == "dateAdded") {
this.filteredTemplateArray.sort(function(a,b) {
if(a.dateAdded < b.dateAdded) {
return 1;
}
if(a.dateAdded > b.dateAdded) {
return -1;
}
return 0;
});
}
if(this.sortBy == "renderTime") {
this.filteredTemplateArray.sort(function(a,b) {
return parseInt(a.renderTime) - parseInt(b.renderTime);
});
}
},
categoryFilter: function(){
if(app.selectedCategories.length!=0){
app.filteredTemplateArray=[];
var templateArray = app.templateArray;
for(i=0; i<app.selectedCategories.length; i++){
var filtered=templateArray.filter(function(template){
var currentCategory=app.selectedCategories[i];
console.log("this is current category"+currentCategory+"end currentCategory");
var returnValue=template.categoryArray.includes(currentCategory);
console.log("this is i"+i+"end i");
console.log("this is return value"+returnValue+"end return value");
return returnValue;
});
console.log(filtered);
app.filteredTemplateArray=app.filteredTemplateArray.concat(filtered);
}
var uniqueArray=[];
var allResultsArray=app.filteredTemplateArray;
for(j=0; j<allResultsArray.length; j++){
if(uniqueArray.indexOf(allResultsArray[j]) == -1){
uniqueArray.push(allResultsArray[j])
}
}
app.filteredTemplateArray=uniqueArray;
} else {app.filteredTemplateArray=app.templateArray;}
this.sortTemplatesBy();
}
}