感谢 Jeremy 的回答,这成为了我们的最终解决方案:
import { autoinject, BindingLanguage, Expression, ViewResources, createOverrideContext } from "aurelia-framework";
// Represents the sequence of static and dynamic parts resulting from parsing a text.
type TemplateStringParts = (Expression | string)[];
// Cache containing parsed template string parts.
const cache = new Map<string, TemplateStringParts>();
/**
* Represents an interpolation expression, such as "The price is ${price | currency}",
* which when evaluated against a binding context results in a formatted string,
* such as "The price is 42 USD".
*/
@autoinject
export class TemplateString
{
private text: string;
private viewResources: ViewResources;
private bindingLanguage: BindingLanguage;
/**
* Creates a new instance of the TemplateString type.
* @param text The text representing the interpolation expression.
* @param viewResources The view resources to use when evaluating the interpolation expression.
* @param bindingLanguage The BindingLanguage instance.
*/
public constructor(text: string, viewResources: ViewResources, bindingLanguage: BindingLanguage)
{
this.text = text;
this.viewResources = viewResources;
this.bindingLanguage = bindingLanguage;
}
/**
* Evaluates the interpolation expression against the specified context.
* @param bindingContext The context against which expressions should be evaluated.
* @param overrideContext The override context against which expressions should be evaluated.
* @returns The string resulting from evaluating the interpolation expression.
*/
public evaluate(bindingContext?: any, overrideContext?: any): string
{
let parts = cache.get(this.text);
if (parts == null)
{
parts = (this.bindingLanguage as any).parseInterpolation(null, this.text) || [this.text];
cache.set(this.text, parts);
}
const scope =
{
bindingContext: bindingContext || {},
overrideContext: overrideContext || createOverrideContext(bindingContext)
};
const lookupFunctions = (this.viewResources as any).lookupFunctions;
return parts.map(e => e instanceof Expression ? e.evaluate(scope, lookupFunctions) : e).join("");
}
/**
* Gets the string representation of this template string.
* @returns The string from which the template string was created.
*/
public toString(): string
{
return this.text;
}
}
/**
* Represents a parser that parses strings representing interpolation expressions,
* such as "The price is ${price | currency}".
*/
@autoinject
export class TemplateStringParser
{
private resources: ViewResources;
private bindingLanguage: BindingLanguage;
/**
* Creates a new instance of the TemplateStringParser type.
* @param resources The view resources to use when evaluating expressions.
* @param bindingLanguage The BindingLanguage instance.
*/
public constructor(resources: ViewResources, bindingLanguage: BindingLanguage)
{
this.resources = resources;
this.bindingLanguage = bindingLanguage;
}
/**
* Parses the specified text as an interpolation expression.
* @param text The text representing the interpolation expression.
* @returns A TemplateString instance representing the interpolation expression.
*/
public parse(text: string): TemplateString
{
return new TemplateString(text, this.resources, this.bindingLanguage);
}
}
要在视图模型中使用它,只需注入TemplateStringParser
并使用它来创建一个TemplateString
实例,然后可以根据上下文对象对其进行评估。