【问题标题】:Overriding javascript Object toString() in a custom typescript class在自定义打字稿类中覆盖 javascript Object toString()
【发布时间】:2018-09-30 07:52:54
【问题描述】:

在过去的几天里,我一直遇到一个问题,我似乎无法在任何地方找到解决方案。 背景: 我有一个 typescript 类定义如下:

export class Client extends Person {
    claimNumber: string;
    policyNumber: string;
    address: string;
    insuranceCompany: Organisation = new Organisation();

    toString(): string {
        return this.policyNumber
            .concat(this.claimNumber);
    }
}

以上用作驱动 angular 5 模板的模型。在我的组件中,我从远程 api 获取(使用 angular 5 HttpClient)客户端列表并生成 html 表行。生成表行的 LOC 是:

<tr *ngFor="let client of clients | filter:searchString"> ... </tr>
上面的

searchString 是绑定到搜索输入标签的属性,而 filter 是定义为的自定义过滤器管道如下:

export class FilterPipe implements PipeTransform {
    transform(items: Client[], term: string) {               
        if (term == undefined || term === '') return items;
        return items.filter(item =>item.toString().toLocaleLowerCase().includes(term.toLocaleLowerCase()));
    }
}

问题: 当我在上面的过滤器管道中检查 item.toString() 时,它返回 [object Object] 而不是由 policyNumber 和 claimNumber 组成的字符串。

调查: 我对这个问题进行了如下调查:我将 Client 类实例化如下:

let c = new Client();
c.policyNumber = 'ababababa';
c.claimNumber = 'aaaaaaa';
console.log('client toString() is => ' + c.toString());

有趣的是,上面的 console.log 输出:'ababababaaaaaaaa'。

问题: 我做错了什么导致过滤器管道中的 item.toString() 返回 [object Object] 而我实例化的类上的 toString() 返回正确的字符串?

【问题讨论】:

  • 您没有检查过滤器中的 item.toString(),而是检查了 policy 和 claimNumbers? API 的数据是如何来的?它看起来怎么样?
  • 我认为您的问题的解决方案在this answer
  • 非常感谢您分享这些链接,它们为找到解决我的问题做出了巨大贡献。

标签: javascript angular typescript


【解决方案1】:

如果您从 WebService(或类似的东西)获取客户端,您将获得普通的 json 对象。如果你说接收到的对象是Client 类型,打字稿会将它们显示为这种类型的对象,但只有属性会相同,方法不会来自Client类,但来自 Object 类。

您可能希望在从服务器检索它们后将它们实例化为真正的客户端对象:

public myServiceMethod() {
    return this.http.get(...).map(plainClients => {
        const realClients: Array<Client> = (plainClients || []).map(plainClient => {
            let realClient = new Client();
            realClient.claimNumber = plainClient.claimNumber;
            realClient.policyNumber = plainClient.policyNumber;
            realClient.address = plainClient.address;
            return realClient;
        });
        return realClients;
    })
}

您可能更喜欢使用类型为接口的贫血对象,并使用实用函数将客户端作为字符串检索,以避免出现类似您遇到的情况:

export interface Person {
    ...
}

export interface Client extends Person {
    claimNumber: string;
    policyNumber: string;
    address: string;
    insuranceCompany: Organisation;
}

// In some utilitarian class
public static getClientInfo(client: Client) {
    return client.policyNumber.concat(client.claimNumber);
}

// In your pipe
return items.filter(item => getClientInfo(item).toLocaleLowerCase().includes(term.toLocaleLowerCase()));

我并不是说只在您的应用程序中使用贫血的类,但如果某种类型的对象被传递并且可能会被序列化,那么使用贫血的对象可以避免像您遇到的那样的问题。

【讨论】:

  • 是的,我假设他将每个客户端实例化为 Client 类的实例。 Typescript 绝对不适合你。
  • 非常感谢,这有助于理解潜在问题并帮助设计解决问题的方法。非常感谢,愿你收到所有的祝福。
【解决方案2】:

找出问题所在的一种方法是将您的方法重命名为不是内置方法名称的名称,例如toSearchString。还值得将控制台日志添加到您的过滤器函数中,以确保您实际上在那里得到clients。你实际上可能得​​到了一个不同的对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 2021-07-31
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多