在打字稿中替换字符串的连接部分

Replace concat part of a string in typescript

我有一个可变字符串,因为它在文本区域内。用户可以写任何东西。之后有一个日期选择器。当我 select 日期时,该值将写入字符串第一部分之后的文本区域中。我有这个功能来改变选择器

concatValue(){
    let dataMsg = "";
    let date: string = moment(dateTime).format('D MMM YYYY, h:mm');
    dataMsg = ". " + date;
    this.message += dataMsg;
  }

这里的问题是,如果我更改日期,字符串会保持连续并且不会重置之前的值。但我无法重置整个 this.message,因为它包含其他文本。我怎么能做这样的事情?例如。第一次

"Hello there at Thursday 15 October 2020, 19:00"

然后我想更改日期:

"Hello there at Friday 16 October 2020, 15:00"

这就是我需要的,而不是

"Hello there at Thursday 15 October 2020, 19:00"
"Hello there at Thursday 15 October 2020, 19:00 Friday 16 October 2020, 15:00"

我打算自己制作 minimal reproducible example 因此,如果您需要对其进行调整以适用于您的用例,希望您可以。想象一下,我有这个 Foo class 需要一个 message 并将日期或时间或其他内容连接到它上面:

class Foo {
    message: string;
    constructor(message: string) {
        this.message = message;
    }
    concatDate() {
        this.message += " @ " + new Date().toLocaleTimeString();
    }
}

let f = new Foo("hello there");
console.log(f.message); // "hello there"
f.concatDate();
console.log(f.message); // "hello there @ 12:56:10 PM"
await new Promise(resolve => setTimeout(resolve, 2000));
f.concatDate();
console.log(f.message); // "hello there @ 12:56:10 PM @ 12:56:12 PM"

哎呀,每次我调用 concatDate() 它都会添加到 message 的末尾。我该如何解决?好吧,一个想法是您可以尝试查看 message 剥离 任何日期字符串(如果有的话)。像这样:

class BadFixFoo {
    message: string;
    constructor(message: string) {
        this.message = message;
    }
    concatDate() {
        this.message = this.message.replace(/ @[^@]*$/, "") + 
          " @ " + new Date().toLocaleTimeString();
    }
}

有点效果:

f = new BadFixFoo("hello there");
console.log(f.message); // "hello there"
f.concatDate();
console.log(f.message); // "hello there @ 12:56:12 PM"
await new Promise(resolve => setTimeout(resolve, 2000));
f.concatDate();
console.log(f.message); // "hello there @ 12:56:14 PM"

直到不起作用:

f = new BadFixFoo("what if I use an @-sign in the message");
console.log(f.message); // "what if I use an @-sign in the message"
f.concatDate();
console.log(f.message); // "what if I use an @ 12:56:14 PM"
await new Promise(resolve => setTimeout(resolve, 2000));
f.concatDate();
console.log(f.message); // "what if I use an @ 12:56:16 PM"

看,我用来删除日期的方法只是在 message 中查找最后一个 @ 符号(在 space 之后),然后删除它和它后面的所有内容.但是如果原来的 message 里面有一个 @ 符号,那么剥离就会把它弄乱。哎呀。也许我们可以写一个更聪明的方法来识别日期字符串,但如果用户真的可以为原始 messageanything,我们就无法阻止他们从写一个实际的日期字符串。我们要去掉 那个吗?


如果不是,您需要重构,这样您就不会试图通过取证来确定原始 message 是什么。相反,存储它:

class GoodFoo {
    originalMessage: string;
    message: string;
    constructor(message: string) {
        this.originalMessage = message;
        this.message = message;
    }
    concatDate() {
        this.message = this.originalMessage + " @ " + new Date().toLocaleTimeString();
    }
}

这意味着 concatDate() 永远不会尝试修改当前的 message。相反,它复制 originalMessage 并附加到 that:

f = new GoodFoo("what if I use an @-sign in the message");
console.log(f.message); // "what if I use an @-sign in the message"
f.concatDate();
console.log(f.message); // "what if I use an @-sign in the message @ 12:56:16 PM"
await new Promise(resolve => setTimeout(resolve, 2000));
f.concatDate();
console.log(f.message); // "what if I use an @-sign in the mssage @ 12:56:18 PM"

Playground link to code