在 Knockout 中搜索可观察数组的问题
Problems Searching Through Observable Array in Knockout
概览
这是一个简单的报价应用程序。我目前正在开发主报价页面,其中显示了所有报价。
问题
我正在尝试在主报价列表中显示客户名称。 (见图)。页面依赖的数据在两个表中:
- Quotes -- 保存报价详情
- Clients -- 保存客户联系信息
表由 client_id
连接(相关)
淘汰赛实施
我定义了一个 class 来保存引号:
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);
}
和客户端Class
let ClientModel = function(id, fullName){
this.id = ko.observable(id);
this.fullName = ko.observable(fullName);
}
在遍历我通过 API 导入的引号时,我正在抓取 client_id,然后调用一个函数来搜索客户端数组,然后return 客户全名。
我不知道如何成功搜索客户数组和 return 全名。
直播URL
您可以在此处看到代码失败:http://quotes.123globalelectronicsllc.com/quotes.html
视图模型
这是视图模型:
// 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);
}
function QuoteViewModel() {
var self = this; // Scope Trick
/* QUOTE Observables */
self.quotes = ko.observableArray();
self.clients = ko.observableArray();
/* 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,
val.created_date,
val.expiration_date,
val.amount,
fullName,
val.status
));
});
});
// Search Client Array, Return Full Name
self.getClientById = function(id){
$.each(self.clients(), function(key, val){
alert(val.fullName);
if(val.id() == id){
return val.fullName();
}
});
}
}
ko.applyBindings(new QuoteViewModel());
你能看出我错在哪里吗?任何帮助将不胜感激。
问题出在您的 getClientById
方法中,特别是您尝试搜索的方式 - 您使用 $.each
遍历元素:
$.each(self.clients(), function(key, val){
alert(val.fullName);
if(val.id() == id){
return val.fullName();
}
});
但是,您不能按照您尝试的方式 return 从 $.each
开始。这是文档中的引述:
We can break the $.each()
loop at a particular iteration by making the callback function return false
. Returning non-false is the same as a continue
statement in a for loop; it will skip immediately to the next iteration.
相反,您可以使用 Array#find
方法:
self.getClientById = function() {
const client = self.clients().find(function(val){
return val.id() == id
}
if(client) {
return client.fullName();
}
return undefined;
}
使用一些 ES6 语法和 short-circuiting
这可以更短
self.getClientById = function() {
const client = self.clients().find(val => val.id() == id);
return client && client.fullName()
}
概览
这是一个简单的报价应用程序。我目前正在开发主报价页面,其中显示了所有报价。
问题
我正在尝试在主报价列表中显示客户名称。 (见图)。页面依赖的数据在两个表中:
- Quotes -- 保存报价详情
- Clients -- 保存客户联系信息
表由 client_id
连接(相关)淘汰赛实施
我定义了一个 class 来保存引号:
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);
}
和客户端Class
let ClientModel = function(id, fullName){
this.id = ko.observable(id);
this.fullName = ko.observable(fullName);
}
在遍历我通过 API 导入的引号时,我正在抓取 client_id,然后调用一个函数来搜索客户端数组,然后return 客户全名。
我不知道如何成功搜索客户数组和 return 全名。
直播URL
您可以在此处看到代码失败:http://quotes.123globalelectronicsllc.com/quotes.html
视图模型
这是视图模型:
// 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);
}
function QuoteViewModel() {
var self = this; // Scope Trick
/* QUOTE Observables */
self.quotes = ko.observableArray();
self.clients = ko.observableArray();
/* 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,
val.created_date,
val.expiration_date,
val.amount,
fullName,
val.status
));
});
});
// Search Client Array, Return Full Name
self.getClientById = function(id){
$.each(self.clients(), function(key, val){
alert(val.fullName);
if(val.id() == id){
return val.fullName();
}
});
}
}
ko.applyBindings(new QuoteViewModel());
你能看出我错在哪里吗?任何帮助将不胜感激。
问题出在您的 getClientById
方法中,特别是您尝试搜索的方式 - 您使用 $.each
遍历元素:
$.each(self.clients(), function(key, val){
alert(val.fullName);
if(val.id() == id){
return val.fullName();
}
});
但是,您不能按照您尝试的方式 return 从 $.each
开始。这是文档中的引述:
We can break the
$.each()
loop at a particular iteration by making the callback function returnfalse
. Returning non-false is the same as acontinue
statement in a for loop; it will skip immediately to the next iteration.
相反,您可以使用 Array#find
方法:
self.getClientById = function() {
const client = self.clients().find(function(val){
return val.id() == id
}
if(client) {
return client.fullName();
}
return undefined;
}
使用一些 ES6 语法和 short-circuiting
这可以更短self.getClientById = function() {
const client = self.clients().find(val => val.id() == id);
return client && client.fullName()
}