【问题标题】:Aurelia - value converter using promiseAurelia - 使用承诺的价值转换器
【发布时间】:2021-03-02 06:10:01
【问题描述】:

我需要使用 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;
            });
        }
}

【问题讨论】:

  • 可以显示formatService的代码吗?
  • 添加了有问题的 FormatService 代码

标签: typescript promise aurelia valueconverter


【解决方案1】:

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

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

【讨论】:

  • 是的,这只是复制错误。实际上,正如我所提到的,FormatService 可以正常工作。它在其他情况下使用,并按预期返回具有格式的 Promise。问题是我无法从 toView 方法返回承诺。它需要一个字符串。并打印出 [Object]。
  • 好的,现在我看到了问题所在。好吧,toView 方法也返回了一个 promise,所以你需要调用 'then'。你能显示使用 toView 的代码吗?还是从视图中使用?
  • 从视图中使用。 ${entity.created |日期时间}
【解决方案2】:

我一直在寻找类似的解决方案,并且非常擅长使用值转换器,因为最初认为这是有道理的;但正如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 的信息。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-22
      • 1970-01-01
      • 1970-01-01
      • 2021-07-11
      相关资源
      最近更新 更多