Javascript 过滤器,如何让它们各自独立运行?

Javascript filters, how to make each of them function independently?

https://www.australianathleticscalendar.com.au/

这个网站本来有一个过滤器,但我又加了一个,希望每个过滤器都独立工作(即按类别(事件)过滤,也按状态过滤)。

它似乎仍然充当一个过滤器,因为我只能 select 在两个过滤器之间设置一个变量。如何调整功能使每个过滤器独立运行?

    function loadCategories() {
    fetch(projectUrl + '/categories')
    .then((response) => response.json())
    .then(json => {
        this.categories = json.categories;
        drawCategories();
    })
}

function loadStates() {
    fetch(projectUrl + '/states')
    .then((response) => response.json())
    .then(json => {
        this.states = json.states;
        drawStates();
    })
}

function drawProducts(products) {
    var template = Handlebars.compile(document.getElementById("products-template").innerHTML);
    document.getElementById('products-container').innerHTML = template({
        title: this.title,
        titleStates:this.titleStates,
        products: products  
    });
}

function drawCategories() {
    var template = Handlebars.compile(document.getElementById("menu-template").innerHTML);
    console.log('draw ', this.products);
    document.getElementById('menu-container').innerHTML = template(this.categories);
}

function drawStates() {
    var template = Handlebars.compile(document.getElementById("menu-template-2").innerHTML);
    console.log('draw ', this.products);
    document.getElementById('menu-container-states').innerHTML = template(this.states);
}

function showAllProducts() {
    this.title = "All Events";
    drawProducts(this.products);
}

function showAllProducts() {
    this.titleStates = "All States";
    drawProducts(this.products);
}

function showCategory(category) {
    this.title = category;
    let filteredProducts = this.products.filter(product => {
        return product.category.toLowerCase().includes(category.toLowerCase());
    }); 
    drawProducts(filteredProducts);
}


function showState(state) {
    this.titleStates = state;
    let filteredProducts = this.products.filter(product => {
        return product.state.toLowerCase().includes(state.toLowerCase());
    }); 
    drawProducts(filteredProducts);
}

它们在菜单中调用,这是两个过滤器:

      <!-- Categories/events filter -->
<div class="container">
    <script id="menu-template" type="text/x-handlebars-template">
            
                <ul class="navbar-nav">
                    {{#each this as |category|}}
                        <li class="nav-item"></li>
                            <a class="nav-link" href="#" onclick="showCategory('{{category.name}}');">{{category.name}}</a>
                        </li>
                    {{/each}}
                    <!-- <a id="all-events" href="#" onclick="showAllProducts();">All Events</a> -->
                    <a class="navbar-brand hover-color" href="#" onclick="showAllProducts();">All Events</a>
                </ul>
                
                <ul class="navbar-nav ml-auto"></ul>
                    <li class="nav-item">
                        
                    </li>
                </ul>

        </div>
    </script>
</div>

<!-- States filter -->
<div class="container">
    <script id="menu-template-2" type="text/x-handlebars-template">
            
                <ul class="navbar-nav">
                    {{#each this as |state|}}
                        <li class="nav-item"></li>
                            <a class="nav-link" href="#" onclick="showState('{{state.name}}');">{{state.name}}</a>
                        </li>
                    {{/each}}
                    <!-- <a id="all-events" href="#" onclick="showAllProducts();">All Events</a> -->
                    <a class="navbar-brand hover-color" href="#" onclick="showAllProducts();">All States</a>
                </ul>
                
                <ul class="navbar-nav ml-auto"></ul>
                    <li class="nav-item">
                        
                    </li>
                </ul>

        </div>
    </script>
</div>

首先,您有一个重复函数 showAllProducts,您还链接到两个不同的按钮。我想你打算有两个不同的功能,每个“全部”按钮一个,所以添加一个名为 showAllEvents 和另一个 showAllStates 的函数,并将它们引用为按钮处理程序。

关于问题:您应该将过滤移至一个函数,该函数将考虑两个过滤器。您可以使用 this.titlethis.titleState 来执行过滤,确保您正确处理“全部”案例。

所以绑定到 HTML 的过滤函数应该变成:

function showAllProducts() {
    this.title = "All Events";
    this.titleStates = "All States";
    drawProducts();
}

function showAllEvents() {
    this.title = "All Events";
    drawProducts();
}

function showAllStates() {
    this.titleStates = "All States";
    drawProducts();
}

function showCategory(category) {
    this.title = category;
    drawProducts();
}

function showState(state) {
    this.titleStates = state;
    drawProducts();
}

注意新功能,因此请确保在 HTML 中引用它们。其次,我从这些函数中删除了过滤,正如我在 drawProducts 中建议的那样。该函数现在不接受任何参数:

function drawProducts() { // remove argument; extend with filtering
    var template = Handlebars.compile(document.getElementById("products-template").innerHTML);
    // Perform filtering here:
    var filteredProducts = this.products.filter(product => {
        return (this.title.slice(0, 4) === "All " || product.category.toLowerCase().includes(this.title.toLowerCase()))
            && (this.titleState.slice(0, 4) === "All " || product.state.toLowerCase().includes(this.titleState.toLowerCase());
    });
    document.getElementById('products-container').innerHTML = template({
        title: this.title,
        titleStates: this.titleStates,
        products: filteredProducts // <--  
    });
}