knockout.js 如何确定是什么触发了计算的可观测量的变化?KnockoutJS

fbcarpbf  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(148)

问题概述

我很难确定是什么触发了一个计算的可观测量的变化。
我有一个下拉选择框,用于过滤表中显示的可观察数组。下面是选择框:

下面是我如何定义select:

// Javascript
let filters = ["All", "Pending", "Accepted", "Rejected", "Expired"];

// HTML
<select data-bind="options: filters, value: filter"> 
</select>

当用户选择一个值时,该计算的可观察值被用于过滤数据的主数组:

self.filteredItems = ko.computed(function() {
        var filter = self.filter();
        if (!filter || filter == "All") {
            return self.quotes();
        } else {
            return ko.utils.arrayFilter(self.quotes(), function(i) {
                console.log(i);
                return i.status() == filter;
            });
        }
    });

正如你所看到的,引号数组中的status属性正在与下拉列表中的过滤器值进行比较。2一切都运行得很好。3但是现在我也在数组中添加了一个关键字搜索(如下图所示):

我将关键字文本字段绑定到一个observable:

self.keyword = ko.observable();

修改代码以处理关键字搜索

我相信我可以很容易地修改计算出的可观察代码来处理关键字搜索,方法是:

return i.status() == filter;

与数组中的其他属性相比)

return i.fullName() == keyword || i.amount() == keyword || ..etc

"但是...“
我不知道该如何决定是用过滤器下拉列表来过滤数组,还是用关键字来过滤数组,但我还是需要知道是什么触发了计算出的可观测量的变化,不是吗?
有什么想法吗?
下面是完整的视图模型:

// Quotes View Model

// +---------------------------------------------------------------------------+
// |  Quote View Model                                                         |
// |                                                                           |
// |  quotes-view-model.js                                                     |
// +---------------------------------------------------------------------------+
// |  Shows a list of all Quotes                                               |
// +---------------------------------------------------------------------------+/

let QuoteModel = function(id, quote_number, created_date, expiration_date, amount, client, status){

     this.id = ko.observable();
     this.quote_number = ko.observable(quote_number);
     this.created_date = ko.observable(created_date);
     this.expiration_date = ko.observable(expiration_date);
     this.amount = ko.observable(amount);
     this.client = ko.observable(client);
     this.status = ko.observable(status);

}

let ClientModel = function(id, fullName){
    this.id = ko.observable(id);
    this.fullName = ko.observable(fullName);
}

// Define Status Dropdown filters
let filters = ["All", "Pending", "Accepted", "Rejected", "Expired"];

function QuoteViewModel() {

    var self = this; // Scope Trick

    /* QUOTE Observables */
    self.quotes = ko.observableArray();
    self.clients = ko.observableArray();

    self.keyword = ko.observable();
    self.searchType = ko.observable();

    self.filters = ko.observableArray(filters);
    self.filter = ko.observable('');

    self.filteredItems = ko.computed(function() {
        var filter = self.filter();
        if (!filter || filter == "All") {
            return self.quotes();
        } else {
            return ko.utils.arrayFilter(self.quotes(), function(i) {
                console.log(i);
                return i.status() == filter;
            });
        }
    });

    /* GET PAGE DATA */

    /* CLIENTS */
           $.getJSON(apiCustomersAll,
            function(data) {
                var fullName;
                $.each(data,
                    function(key, val) {
                        fullName = val.first_name + " " + val.last_name;
                        self.clients.push(new ClientModel(val.id, fullName));
                    });
            });

          $.getJSON(apiQuotesAll,
            function(data) {
                var fullName;
                $.each(data,
                    function(key, val) {
                        fullName = self.getClientById(val.client_id);
                        console.log(`Full name is ${fullName}`);
                        self.quotes.push(new QuoteModel(val.id, 
                                                        val.quote_number, 
                                                        formatDate(val.created_date), 
                                                        formatDate(val.expiration_date), 
                                                        val.amount, 
                                                        fullName, 
                                                        val.status
                                                      ));
                    });
            });

        // Search Client Array, Return Full Name
        self.getClientById = function(id) {
            const client = self.clients().find(function(val){
                return val.id() == id;
            });

            if(client) {
                return client.fullName();   
            }

            return undefined;
            }

       self.search = function(){
         // to do
       }

}

ko.applyBindings(new QuoteViewModel());
rryofs0p

rryofs0p1#

只使用一个 textbox 来允许自由文本搜索会增加过滤器的复杂性,我可以理解您为什么要添加searchType可观察项。但是,您可以测试输入的文本是否可以被视为 amount,然后使用此检查来区分过滤器。我相信当您检查金额是否大于插入值时,过滤器会更有用。而不是检查是否完全相等,由您决定。
此外:由于这些过滤器的组合将应用于两个实体(报价和客户端),您也可以决定是否将自由文本过滤器应用为两个数据集之间的 * 交集 * 或 * 并集 。在我下面的建议中,我将再次过滤结果数据集( 交集 *):
第一个

相关问题