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.”
