Aurelia - 使用承诺的价值转换器

时间:2016-04-19 08:30:38

标签: typescript promise aurelia valueconverter

我需要使用promise返回的格式来格式化Date。我尝试从toView(value)返回promise。但这不起作用。

@autoinject
export class DateTimeValueConverter {

    constructor(private formatService:FormatService) {
    }

    toView(value) {
        return this.formatService.getFormat().then(format=>
            moment(value).format(format)
        );
    }

}

这是格式化服务的代码,可以正常使用

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;
            });
        }
}

3 个答案:

答案 0 :(得分:3)

据我所知,您不能在值转换器中使用异步功能。我看到的一个解决方案是将format作为参数从viewmodel传递给值转换器(通过视图)。但这意味着您需要在viewmodel中获取格式,这种类型会破坏整个值转换器......

我看到的另一个解决方案是调整FormatService,以便缓存格式(假设&#39;格式&#39;不经常更改)。这样,getFormat函数将是同步的,您可以在值转换器中使用它。当然,在调用任何值转换器之前,您需要找到一种在format内初始化FormatService的方法。

答案 1 :(得分:0)

我一直在寻找类似的解决方案,因此非常想使用值转换器,因为从最初的想法出发,这才有意义。但正如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的信息。

答案 2 :(得分:0)

其实是有可能的。您需要绑定行为,这将等到值转换器承诺得到解决。我发现 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>

附言不要忘记导入 asyncBindingBehavior

<require from="./asyncBindingBehavior"></require>