javascript - 在 Knockout 中搜索可观察数组时出现问题

标签 javascript knockout.js

概述

这是一个简单的报价应用程序。我目前正在开发主报价页面,其中显示所有报价。

问题

我正在尝试在主报价列表中显示客户名称。 (见图)。页面依赖的数据在两个表中:

enter image description here

  1. 报价 -- 保存报价详细信息
  2. 客户 - 保存客户联系信息

这些表通过client_id连接(相关)

knockout 实现

我定义了一个类来保存引号:

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);
}

在循环通过 API 导入的引号时,我获取 client_id,然后调用一个函数来搜索客户端数组并返回客户端的全名。

我不知道如何成功搜索客户端数组并返回全名。

实时网址

您可以在此处看到代码失败:http://quotes.123globalelectronicsllc.com/quotes.html

View 模型

这是 View 模型:

// 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();   
  }
});

但是,您不能按照您想要的方式从 $.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()
}

关于javascript - 在 Knockout 中搜索可观察数组时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59588527/

相关文章:

javascript - 如何删除从列表中呈现的组件? react native

javascript - reactjs Hook 中连续状态对象设置的问题

javascript - 与 asp.net MVC3 和 knockout js 库一起使用的最佳 ViewModel javascript 文件组织是什么?

jquery - 使用 KnockoutJS 加载日历事件

javascript - knockout validation - 动态验证消息

JavaScript 正则表达式 : Delete line with string occurrence and following two lines

javascript - 如何在 vs code 中完全删除 prettier code-formatter 插件?

javascript - 使用 afterRender 功能实现 knockout 自定义绑定(bind)

javascript - 是否有用 JavaScript 实现 RFC3987(IRI 验证)?

javascript - knockout : How to pass data-bound input value back to function on click?