Aurelia - 使用 promise 的值转换器
Aurelia - value converter using promise
我需要使用 promise 返回的格式来格式化日期。我尝试从 toView(value) 返回承诺。但那是行不通的。
@autoinject
export class DateTimeValueConverter {
constructor(private formatService:FormatService) {
}
toView(value) {
return this.formatService.getFormat().then(format=>
moment(value).format(format)
);
}
}
这是 FormatService 的代码,可以正常工作
export class FormatService {
private format;
constructor(private http:AppHttp) {
this.format= null;
}
public getFormat() : Promise<string>{
if (this.format){
var promise = new Promise<string>((resolve, reject)=>{
resolve(this.format);
});
return promise;
}
return this.http.get('format')
.then((format) => {
if (format){
this.format= format;
}
return format;
});
}
}
据我所知,您不能在值转换器中使用异步功能。我看到的一种解决方案是将 format
作为参数从视图模型传递到值转换器(通过视图)。但这意味着您需要在视图模型中获取格式,这会破坏整个值转换器点...
我看到的另一个解决方案是调整 FormatService
以便它缓存格式(假设 'format' 不经常更改)。这样,getFormat
函数将是同步的,您可以在值转换器中使用它。当然,在调用任何值转换器之前,您需要找到一种在 FormatService
内初始化 format
的方法。
我一直在寻找类似的解决方案,并且非常喜欢使用值转换器,因为最初认为这是有道理的;但正如 fikkatra 提到的那样,目前这是不可能的。经过一些挖掘后,更好的解决方案是使用绑定行为来获得所需的效果。
因此,将该 DateTimeValueConverter 转换为绑定行为如下所示:
@autoinject
export class DateTimeBindingBehavior {
constructor(private formatService:FormatService) {
}
public bind(binding, source) {
binding.originalUpdateTarget = binding.updateTarget;
binding.updateTarget = value => {
this.formatService.getFormat().then(format =>
moment(value).format(format)
);
};
}
public unbind(binding) {
binding.updateTarget = binding.originalUpdateTarget;
binding.originalUpdateTarget = null;
}
}
以下是您如何在您的视图中使用它的示例:
<div>${someDate & dateTime}</div>
类似于值转换器,您也可以向它们传递参数,您可以阅读有关 here。
其实是有可能的。您需要绑定行为,它将等到值转换器承诺得到解决。我发现 this article 具有这种异步绑定行为
它适用于承诺值和值转换器
在您的情况下,您需要创建 asyncBindingBehavior
export class asyncBindingBehavior {
bind(binding, source, busymessage) {
binding.originalupdateTarget = binding.updateTarget;
binding.updateTarget = (a) => {
if (typeof a.then === 'function') {
if (busymessage)
binding.originalupdateTarget(busymessage);
a.then(d => { binding.originalupdateTarget(d); });
}
else
binding.originalupdateTarget(a);
};
}
unbind(binding) {
binding.updateTarget = binding.originalupdateTarget;
binding.originalupdateTarget = null;
}
}
并与值转换器一起使用
<span>${ Date.now() | dateTime & async }</span>
P.S。不要忘记导入 asyncBindingBehavior
<require from="./asyncBindingBehavior"></require>
我需要使用 promise 返回的格式来格式化日期。我尝试从 toView(value) 返回承诺。但那是行不通的。
@autoinject
export class DateTimeValueConverter {
constructor(private formatService:FormatService) {
}
toView(value) {
return this.formatService.getFormat().then(format=>
moment(value).format(format)
);
}
}
这是 FormatService 的代码,可以正常工作
export class FormatService {
private format;
constructor(private http:AppHttp) {
this.format= null;
}
public getFormat() : Promise<string>{
if (this.format){
var promise = new Promise<string>((resolve, reject)=>{
resolve(this.format);
});
return promise;
}
return this.http.get('format')
.then((format) => {
if (format){
this.format= format;
}
return format;
});
}
}
据我所知,您不能在值转换器中使用异步功能。我看到的一种解决方案是将 format
作为参数从视图模型传递到值转换器(通过视图)。但这意味着您需要在视图模型中获取格式,这会破坏整个值转换器点...
我看到的另一个解决方案是调整 FormatService
以便它缓存格式(假设 'format' 不经常更改)。这样,getFormat
函数将是同步的,您可以在值转换器中使用它。当然,在调用任何值转换器之前,您需要找到一种在 FormatService
内初始化 format
的方法。
我一直在寻找类似的解决方案,并且非常喜欢使用值转换器,因为最初认为这是有道理的;但正如 fikkatra 提到的那样,目前这是不可能的。经过一些挖掘后,更好的解决方案是使用绑定行为来获得所需的效果。
因此,将该 DateTimeValueConverter 转换为绑定行为如下所示:
@autoinject
export class DateTimeBindingBehavior {
constructor(private formatService:FormatService) {
}
public bind(binding, source) {
binding.originalUpdateTarget = binding.updateTarget;
binding.updateTarget = value => {
this.formatService.getFormat().then(format =>
moment(value).format(format)
);
};
}
public unbind(binding) {
binding.updateTarget = binding.originalUpdateTarget;
binding.originalUpdateTarget = null;
}
}
以下是您如何在您的视图中使用它的示例:
<div>${someDate & dateTime}</div>
类似于值转换器,您也可以向它们传递参数,您可以阅读有关 here。
其实是有可能的。您需要绑定行为,它将等到值转换器承诺得到解决。我发现 this article 具有这种异步绑定行为
它适用于承诺值和值转换器
在您的情况下,您需要创建 asyncBindingBehavior
export class asyncBindingBehavior {
bind(binding, source, busymessage) {
binding.originalupdateTarget = binding.updateTarget;
binding.updateTarget = (a) => {
if (typeof a.then === 'function') {
if (busymessage)
binding.originalupdateTarget(busymessage);
a.then(d => { binding.originalupdateTarget(d); });
}
else
binding.originalupdateTarget(a);
};
}
unbind(binding) {
binding.updateTarget = binding.originalupdateTarget;
binding.originalupdateTarget = null;
}
}
并与值转换器一起使用
<span>${ Date.now() | dateTime & async }</span>
P.S。不要忘记导入 asyncBindingBehavior
<require from="./asyncBindingBehavior"></require>