代码之家  ›  专栏  ›  技术社区  ›  Ben

如何使用带有部分应用的过滤器功能的角度材质日期选择器?

  •  1
  • Ben  · 技术社区  · 1 年前

    我一直在尝试使用Angular Materials日期选择器组件创建一个日期选择器/输入。

    我正在迭代一组报告,并需要为每个报告创建一个输入,在它旁边。 每个报告上都有一个自定义日期,超过该日期将应用自定义过滤器,将允许的日期基本上转换为瑞士奶酪。换句话说,规则对于min/max来说太复杂了,我需要使用过滤函数, 把个人报告交给它。

    在实现这一点时,我偶然发现了一个特别有趣的行为:Angular无法处理过滤器函数的lambda。 这是我写的一张罚单(显然这是意料之中的行为)

    Github Issue

    Stackblitz

    要点是,更改检测中的循环将导致表达式被无限期地重新评估,因为它每次都是一个新的lambda。使用OnPush变化检测策略在这里没有效果,它仍然是一个循环。

    我希望将循环变量(“@for( 汇报 报告的数量;跟踪报告){}“) 带有过滤器。我需要访问TypeScript中的这个模板循环变量。

    这通常是可能的,但[matDatepickerFilter]不支持$event。

    使用返回与过滤函数类型兼容的lambda的函数在纸面上是可行的,但在实践中会导致组件停止工作(请参阅stackblitz)。

    似乎没有办法让“matInput”或“matNativeControl”实现“exportAs”,所以“#var=matInput”也是不可能的。

    更改更改检测策略也不能防止出现此问题。 我没有主意了。

    我可以使用哪些设计模式将报告与输入关联起来,并根据该报告为日期选择器设置过滤器?

    我可以提供一个更完整的Stacklitz,如果有帮助的话,也可以编辑当前的。

    1 回复  |  直到 1 年前
        1
  •  0
  •   Silvermind    1 年前

    因此,基本上它会强制您为应用的过滤器提供一个参考。 如果过滤器基于每个项目的某些自定义逻辑,则可以尝试保留对创建的过滤器的引用。

    例如

    打字稿:

    private readonly filters = new Map<HTMLInputElement, (arg: Moment | Date | null) => boolean>();
    
    filter2(element: HTMLInputElement): (arg: Moment | Date | null) => boolean {
      let filter = this.filters.get(element);
      if (filter) {
        return filter;
      }
      filter = (arg: Moment | Date | null) => true;
      this.filters.set(element, filter);
      return filter;
    }
    

    Html

    <mat-form-field>
      <mat-label> Borked </mat-label>
      <input
        matInput
        #dateBox2
        [ngModel]="date2"
        [matDatepicker]="datePicker2"
        [matDatepickerFilter]="filter2(dateBox2)"
      />
      <mat-datepicker-toggle matIconSuffix [for]="datePicker2" />
      <mat-datepicker #datePicker2 />
    </mat-form-field>
    

    StackBlitz