简体   繁体   English

Aurelia动态边界值转换器

[英]Aurelia Dynamically Bound Value Converter

I'm running into an issue with Aurelia and am assuming that there is something I am missing. 我遇到了Aurelia的问题,并假设我缺少某些东西。

I'm trying to create a 'generic' grid. 我正在尝试创建一个“通用”网格。 I have removed a lot of the html to keep the example short, but the basic idea is this: 为了使示例简短,我删除了很多html,但是基本思路是这样的:

<template>
<require from="../value-converters"></require>
  <table show.bind="rows.length">
    <thead>
      <tr>
        <th repeat.for="columnDefinition of columnDefinitions">
          ${columnDefinition.displayName}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr repeat.for="row of rows">
        <td repeat.for="columnDefinition of columnDefinitions">
          <span if.bind="columnDefinition.isCurrency">${row[columnDefinition.propertyName] | numeralFormatter}</span>
          <span if.bind="columnDefinition.isDate">${row[columnDefinition.propertyName] | dateFormatter}</span>
          <span if.bind="!columnDefinition.isCurrency && !columnDefinition.isDate &&">${row[columnDefinition.propertyName]}</span>
        </td>
      </tr>
    </tbody>
  </table>
</template>

I want to be able to use the ValueConverters to help properly display certain types of column data. 我希望能够使用ValueConverters帮助正确显示某些类型的列数据。 The above is currently working, but I want to have more value converters for other columns and the conditions will get unwieldy. 上面的代码当前正在工作,但是我想为其他列提供更多的值转换器,并且条件将变得笨拙。 My experience with Aurelia so far is that it offers fairly elegant solutions, but I have been unable to figure this one out as of yet. 到目前为止,我对Aurelia的经验是它提供了相当优雅的解决方案,但是到目前为止,我还无法弄清楚这一点。

I tried adding another property to the columnDefinition class like this formatter:string = undefined and then tried to create the spans like the following: 我尝试将另一个属性添加到columnDefinition类,例如该formatter:string = undefined ,然后尝试创建如下所示的跨度:

<span if.bind="columnDefinition.formatter">${row[columnDefinition.propertyName] | columnDefinition.formatter}</span>
<span if.bind="!columnDefinition.formatter">${row[columnDefinition.propertyName]}</span>

but the parser threw an error on the '.'. 但解析器在“。”上引发了错误。

Is there any way to achieve this? 有什么办法可以做到这一点? What is the 'aurelia-way' of dealing with this type of a problem. 什么是解决这类问题的“奥里亚方法”。

Thanks in advance for any help that could be offered. 在此先感谢您可以提供的任何帮助。

I ended up taking a similar approach to the one suggested by @Slyvain with a bit of a different twist: 我最终采取了与@Slyvain建议的方法类似的方法, 但又有所不同:

import {DateValueConverter} from './date';
import {NumberValueConverter} from './number';
import {autoinject} from 'aurelia-framework';

@autoinject()
export class MetaValueConverter {
    constructor(private date: DateValueConverter,
                private number: NumberValueConverter) {
    }

    public toView(value, valueConverter, format) {
        /* JUSTIFICATION: https://stackoverflow.com/questions/38898440/aurelia-dynamically-bound-value-converter#comment-65199423 */
        /* tslint:disable:no-string-literal */
        if (this[valueConverter] && this[valueConverter].toView) {
            return this[valueConverter].toView(value, format);
        } else {
            return value;
        }
    }

    public fromView(val, valueConverter, format) {
        if (this[valueConverter] && this[valueConverter].fromView) {
            return this[valueConverter].fromView(value, format);
        } else {
            return value;
        }
    }
}

Original code can be found here . 原始代码可以在这里找到。

Hope this helps. 希望这可以帮助。

I followed @peinearydevelopment and went one step further again to create a fully dynamic value converter. 我遵循@peinearydevelopment,并再进一步走一步,以创建一个完全动态的值转换器。

Usage is as follows ${myValue | dynamic:converterKey:converterArgs} 用法如下${myValue | dynamic:converterKey:converterArgs} ${myValue | dynamic:converterKey:converterArgs} or simply ${myValue | dynamic:converterKey} ${myValue | dynamic:converterKey:converterArgs}或简单地${myValue | dynamic:converterKey} ${myValue | dynamic:converterKey} if no additional arguments are required. ${myValue | dynamic:converterKey}如果不需要其他参数)。 The converterKey is used to request a value converter that should be registered with the container. converterKey用于请求应在容器中注册的值转换器。 converterArgs is the array of arguments that you'd pass to the toView & fromView functions. converterArgs是要传递给toViewfromView函数的参数数组。

import { autoinject, Container } from 'aurelia-dependency-injection';

export type ValueConverterKey = new (...args: any[]) => object;

type ValueConverterFunc = (...args: any[]) => any;

interface ValueConverter {
  toView?: ValueConverterFunc;
  fromView?: ValueConverterFunc;
}

@autoinject()
export class DynamicValueConverter {
    constructor(
      private container: Container,
    ) { }

    public toView(value: any, converterKey?: ValueConverterKey, ...converterArgs: any[]) {
      if (!converterKey) {
        return value;
      }

      return this.convertValueIfPossible(value, converterKey, converterArgs, 'toView');
    }

    public fromView(value: any, converterKey?: ValueConverterKey, ...converterArgs: any[]) {
      if (!converterKey) {
        return value;
      }

      return this.convertValueIfPossible(value, converterKey, converterArgs, 'fromView');
    }

    private convertValueIfPossible(value: any, converterKey: ValueConverterKey, converterArgs: any[], func: keyof ValueConverter) {
      let converter = this.container.get(converterKey);

      if (converter) {
        let converterFunc = converter[func];

        if (converterFunc) {
          return converterFunc.call(converter, value, ...converterArgs);
        }
      }

      return value;
    }
}

Have you considered using a single <span> with a single general purpose converter that takes the column definition as a parameter and that delegates to the right converter? 您是否考虑过将单个<span>与单个通用转换器一起使用,该通用转换器将列定义作为参数并委派给正确的转换器? I think that would make the component markup simpler. 我认为这会使组件标记更简单。

<span>${row[columnDefinition.propertyName] | formatCell:columnDefinition}</span>

And inside the formatter: 在格式化程序中:

export class FormatCell {
  toView(value, columnDefinition){
    if(columnDefinition.isCurrency)
        return new CurrencyConverter().toView(value);

    if(columnDefinition.isDate)
        return new DateConverter().toView(value);

    return value;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM