Javascript 我如何确定是什么触发了一个计算的可观测的变化?淘汰赛 问题概述
我很难确定是什么触发了计算的可观测变化 我有一个下拉选择框,用于过滤表中显示的可观察数组。以下是选择框中的选项: 以下是我如何定义选择:Javascript 我如何确定是什么触发了一个计算的可观测的变化?淘汰赛 问题概述,javascript,knockout.js,Javascript,Knockout.js,我很难确定是什么触发了计算的可观测变化 我有一个下拉选择框,用于过滤表中显示的可观察数组。以下是选择框中的选项: 以下是我如何定义选择: // Javascript let filters = ["All", "Pending", "Accepted", "Rejected", "Expired"]; // HTML <select data-bind="options: filters, value: filter"> </select> 如您所见,引号数组中的
// Javascript
let filters = ["All", "Pending", "Accepted", "Rejected", "Expired"];
// HTML
<select data-bind="options: filters, value: filter">
</select>
如您所见,引号数组中的status属性与下拉列表中的过滤器值进行比较。一切都很好。但现在我也在数组中添加关键字搜索(如下图所示):
我将关键字文本字段绑定到可观察的:
self.keyword = ko.observable();
修改代码以处理关键字搜索
我相信通过更改以下内容,我可以轻松修改计算的可观察代码以处理关键字搜索:
return i.status() == filter;
类似于此(与数组中的其他属性相比)
但是
我不知道如何确定是通过过滤器下拉列表过滤数组,还是通过关键字过滤数组。不知何故,我需要知道是什么触发了计算的可观测变化,不是吗
有什么想法吗
以下是完整的视图模型:
// 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());
仅使用一个文本框来允许自由文本搜索将给过滤器增加一些复杂性,我可以理解为什么您添加了searchType
observable。但是,您可以测试键入的文本是否可以被视为数量,然后使用此检查区分过滤器。我相信,当您检查数量是否大于插入值时,过滤器会更有用,而不是检查是否完全相等,具体取决于您
此外:由于这些过滤器的组合将应用于两个实体(引号和客户机),因此自由文本过滤器应作为两个数据集之间的交集或并集应用,也取决于您。在我下面的建议中,我再次过滤生成的数据集(交叉点):
var quoteStatusOptions=[“全部”、“待定”、“接受”、“拒绝”、“过期”];
风险值数据={
引号:[{id:1,客户机:1,金额:300,状态:“待定”},{id:2,客户机:3,金额:200,状态:“已接受”},{id:3,客户机:2,金额:100,状态:“已过期”},
客户:[{id:1,全名:“Leanne Graham”},{id:2,全名:“Ervin Howell”},{id:3,全名:“Clementine Bauch”}]
};
函数QuoteModel(数据){
this.id=ko.可观察(data.id);
this.client=ko.observable(data.client);
本金额=可观察到的ko(数据金额);
this.status=ko.可观察(data.status);
}
函数ClientModel(数据){
this.id=ko.可观察(data.id);
this.fullName=ko.observable(data.fullName);
}
函数QuoteViewModel(数据){
var self=这个;
self.quotes=ko.observearray(ko.utils.arrayMap(data.quotes,function)(quote){
返回新的QuoteModel(quote);
}));
self.quoteStatusOptions=ko.observearray(quoteStatusOptions);
self.quoteStatusFilter=ko.可观察(“”);
self.clients=ko.observearray(ko.utils.arrayMap(data.clients,function(client)){
返回新的ClientModel(客户端);
}));
self.searchTextFilter=ko.可观察(“”);
self.filteredQuotes=ko.computed(函数(){
var quotes=self.quotes();/*跟踪引号数组更改*/
var quoteStatusFilter=self.quoteStatusFilter();/*跟踪报价状态筛选器更改*/
var clients=self.clients();/*跟踪客户端数组更改*/
var searchTextFilter=self.searchTextFilter();/*跟踪文本筛选器更改*/
var isAmount=!isNaN(parseFloat(searchTextFilter))&&isFinite(searchTextFilter);
var filteredQuotes=ko.utils.arrayFilter(引号,函数(引号){
var includeAll=!QUOTESTATUSPILTER | QUOTESTATUSPILTER==“全部”;
var includeByStatus=includeAll | | quote.status.peek()==quoteStatusFilter;
var includebamount=parseFloat(quote.amount.peek())>=parseFloat(searchTextFilter);
返回isAmount?includeByStatus&&includeByAmount:includeByStatus;
});
var filteredClients=ko.utils.arrayFilter(客户端,函数(客户端){
var includeal=searchTextFilter==“”;
var includeByName=~client.fullName.peek().toLowerCase().indexOf(searchTextFilter.toLowerCase());
return isAmount?true:includeAll | | includeByName;
});
var结果=[];
对于(var i=0,l=filteredQuotes.length;我“不知何故,我需要知道是什么触发了计算的可观测值的改变,不是吗?”事实上,你没有,因为从用户体验的角度来看,一旦任何一个条件发生变化,用户都会希望你根据这两个条件过滤数组,而不管哪一个条件发生了变化。哦,等等,我想我明白了……你是说我应该保持原样,只需将关键字过滤逻辑与状态一起添加吗?如果是,w我需要使用&&和| |吗?你能给我一个例子,说明我如何将逻辑添加到当前函数中来处理关键字吗?你已经自己选择了它,所以这很好。你所需要做的就是将你的状态
比较与关键字
比较组合成一个布尔表达式(也就是说,在它们之间使用&&
,同时将您的|
放在每个代码中)。
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());