ค้นหาเว็บไซต์

typescript - วิธีใช้การแทรกค่า ${text} จากตัวแปรใน Angular?


คำถามนี้เกี่ยวกับการแทรกข้อความแบบอินไลน์ของ ts ใน Angular (ไม่ใช่การแทรกในเทมเพลตสำหรับไฟล์ HTML)

ฉันไม่สามารถหาข้อมูลที่เกี่ยวข้องกับคำถามของฉันได้ ดังนั้นฉันจึงไม่แน่ใจว่าสามารถทำได้หรือไม่ ขอขอบคุณเป็นอย่างยิ่งหากคุณสามารถให้เอกสารอ้างอิงในกรณีที่สิ่งที่ฉันถามไม่สามารถทำได้

ตอนนี้ฉันสามารถทำสิ่งต่อไปนี้ได้:

export class SomeClass {
    parseString(name: string): string {
        const baseString = `
            Hello ${name}...
        `;
        return baseString;
    }
}

// later... when `parseString` is called I get the following result:
parseString('John');                             // Hello John...
parseString('Mr. Smith');                        // Hello Mr. Smith...

สิ่งที่ฉันต้องการทำคืออะไรบางอย่างที่คล้ายกับนี้:

export class SomeClass {
    parseString(name: string, baseString: string): string {
        return baseString;
    }
}
// later... when `parseString` is called I want to get the following result:
parseString('John', `Hello Mr.${name}`);         // Hello Mr.John...
parseString('Mr. Smith', `Hi ${name}`);          // Hi Mr. Smith...

ไวยากรณ์ที่ฉันเสนอไปนั้นผิดทั้งหมดเพราะ baseString ถูกประเมินค่าก่อนที่ name จะมีอยู่ในสโคปของมันหรือมีค่า ดังนั้นมันจึงมักจะส่งกลับสตริงโดยไม่มีค่าตัวแปร: Hello Mr. และ Hi

ฉันไม่สนใจเกี่ยวกับไวยากรณ์ วิธีใด ๆ สำหรับการใช้ประโยชน์จากการแทรกข้อความจากตัวแปรก็ได้ สุดท้ายฉันอยากจะสามารถทำบางอย่างแบบนี้:

/** 
 * The reason that I'm using `of` from `RxJS` is that 
 * I want to show that I want to be able to gather labels from
 * anywhere, let's say a REST API or a service (?)
 **/
of(`Greetings ${name}...`).subscribe(val => {
  const name = 'John';
  console.log(val);                              // Greetings John...
});

ปัจจุบัน เพื่อที่จะทำสิ่งเหล่านี้ทั้งหมดให้สำเร็จ ฉันเพียงแค่ใช้:

parseString(name: string, baseString: string): string {
    return baseString.replace(/\$\{name\}/g, 'John');
}

แต่ฉันสงสัยว่ามีฟีเจอร์อะไรที่ฉันพลาดในการแทรกข้อความหรือเปล่า

แก้ไข :

ความแตกต่างหลักระหว่างคำถามนี้กับคำถามที่ถูกแนะนำซ้ำ ๆ คือคำถามที่ถูกแนะนำไม่ได้สนใจว่าข้อความที่ถูกคั่นด้วยอักขระหนีอาจจะเป็นแบบไดนามิก ที่นี่ฉันพยายามที่จะสามารถ 'สร้าง' ข้อความที่ถูกคั่นด้วยอักขระหนีนั้นจากศูนย์หรือจากตัวแปรอื่น

แก้ไข 2:

คำถามที่ซ้ำกันที่แนะนำตอบคำถามของฉันที่นี่ได้ แต่ใช้งานได้เฉพาะในสภาพแวดล้อม ES6 เท่านั้น

แก้ไข 3:

อธิบายโดยสั้น ๆ เกี่ยวกับปัญหา ES5 กับ ES6 ผมตระหนักว่าคำถามซ้ำที่แนะนำจะสร้างวัตถุ Function ในระหว่างรันไทม์ ซึ่งมีไวยากรณ์ที่มีเฉพาะใน ES6 ซึ่งหมายความว่ามันจะไม่ทำงานในสภาพแวดล้อม ES5 ตรงกันข้าม ตัวคอมไพเลอร์ Angular TypeScript สามารถสร้างโค้ดที่เข้ากันได้กับ ES5 เมื่อใช้การแทรกข้อความ

คำตอบ #1

ลองอันนี้

/**
 * Text interpolation
 * https://www.w3schools.com/js/js_string_templates.asp
 *
 * Example:
 *   const text: string = this.helloI18nTag; // <-- "Hello ${name}, welcome"
 *   const res = StringUtil.interpolate(text, { name: 'John Connor' });
 *   console.log(res);                       // <-- "Hello John Connor, welcome"
 *
 * @param template : string to interpolate
 * @param args     : an object wiht key -> value to replace
 * @returns
 */
public static interpolate(template: string, args: { [key: string]: string }): string {
    if (typeof args !== 'object') {
      return template;
    }
    try {
      return new Function('return `' + template.replace(/\$\{(.+?)\}/g, '${this.$1}') + '`;').call(args);
    } catch (e) {
      // ES6 syntax not supported
    }
    Object.keys(args).forEach((key) => {
      template = template.replace(new RegExp('\\$\\{' + key + '\\}', 'g'), args[key]);
    });
    return template;
}
interpolate('Hello ${name}', {name: 'John'});

คำตอบ #2

ถ้าสิ่งเดียวที่คุณทำอยู่ตลอดเวลาคือการต่อ baseString และ name คุณก็สามารถทำดังนี้ได้:

parseString(name: string, baseString: string): string {
    return baseString + name;
}

หรือหากมันจะไม่ง่ายเช่นนั้นเสมอไป คุณสามารถส่งฟังก์ชันแทน baseString:

// inside class
parseString(name: string, greeting: (s: string) => string): string {
    return greeting(name);
}

function makeGreeting(name: string) { 
   return `Hi ${name}, I’m Jack.`;
}

console.log(parseString("Bill", makeGreeting)); // “Hi Bill, I’m Jack.”