【问题标题】:How to use Angular Material MAT_AUTOCOMPLETE_DEFAULT_OPTIONS injection token如何使用 Angular Material MAT_AUTOCOMPLETE_DEFAULT_OPTIONS 注入令牌
【发布时间】:2018-10-28 09:13:09
【问题描述】:

使用 MAT_AUTOCOMPLETE_DEFAULT_OPTIONS 注入令牌或 const AUTOCOMPLETE_OPTION_HEIGHT 自定义 mat-autocomplete 的方法是什么。这些常量等在公共 API here 中公开,但没有关于如何使用它们的文档

【问题讨论】:

    标签: angular angular-material


    【解决方案1】:

    MAT_AUTOCOMPLETE_DEFAULT_OPTIONS 添加到模块的providers 数组中,如下所示:

    providers: [
      // ...
      {provide: MAT_AUTOCOMPLETE_DEFAULT_OPTIONS, useValue: {autoActiveFirstOption: false}}
    ]
    

    至于其他常量,我不确定您是否可以调整它们。您可能不得不使用 CSS 样式,例如查看 this issue 以调整面板高度。

    【讨论】:

    • Thanx Jeto,我认为该令牌也可以帮助我设置每个选项的高度。事实是,用 css 设置高度是不费吹灰之力的。问题是当使用箭头键导航列表时,列表向上滚动的速度比需要的快得多,因为材料认为每个选项的高度都是 48 像素。这就是为什么我需要更改选项 hight 常量,以使滚动策略正常工作。
    • @Gidon 你找到如何覆盖常量值了吗?
    • @MatiasFernandezMartinez 不
    【解决方案2】:

    这很奇怪,为什么像项目(选项)的高度这样需要的选项没有定义为输入。

    因为不更改 AUTOCOMPLETE_OPTION_HEIGHT 我们会得到一个错误 (https://github.com/angular/components/issues/18030)

    这是一个可能的解决方案:

    步骤 1. 改变风格。

    这是最轻松的时刻。我们可以改变全局样式。让我们用 24px 代替 48px

    mat-option.mat-option{
        position: relative;
        height: 24px!important;
        line-height: 24px!important;
        max-height: 24px!important;
    }
    
    步骤 2. 覆盖 MatAutocompleteTrigger 的原始 _scrollToOption 方法

    痛点在这里:https://github.com/angular/components/blob/49a1324acc05cec1c5ff28d729abfe590f6772dd/src/material/autocomplete/autocomplete-trigger.tsline 498,方法_scrollToOption

    此方法采用两个硬编码常量(AUTOCOMPLETE_OPTION_HEIGHTAUTOCOMPLETE_PANEL_HEIGHT)并使用它来计算新的滚动位置。当然,如果你没有 48px,但或多或​​少 - 它将无法正常工作。

    所以,我们必须覆盖这个方法。

    最优雅的方法 - 使用Directive(请记住,我们可以使用@ViewChild() 访问MatAutocompleteTrigger 并在父组件的范围内更改它,但这不是可重用的解决方案) .

    步骤 2.1。创建指令
    import { Directive } from '@angular/core';
    import { Host, Self, Optional, Input, OnInit } from '@angular/core';
    import { MatAutocompleteTrigger, AUTOCOMPLETE_OPTION_HEIGHT, AUTOCOMPLETE_PANEL_HEIGHT } from '@angular/material';
    import {
      _countGroupLabelsBeforeOption,
      _getOptionScrollPosition
    } from '@angular/material/core';
    
    @Directive({
        selector: '[matAutocompleteTriggerAccessor]',
    })
    
    export class DirectiveAccessor implements OnInit {
    
        @Input() optionHeight: number = AUTOCOMPLETE_OPTION_HEIGHT;
        @Input() panelHeight: number = AUTOCOMPLETE_PANEL_HEIGHT;
    
        constructor(
          @Host() @Self() @Optional() public _refTrigger: MatAutocompleteTrigger
        ) { }
    
        public ngOnInit() {
          if (this._refTrigger === undefined || this._refTrigger === null) {
            return;
          }
          this._refTrigger['_scrollToOption'] = this._scrollToOption.bind(this._refTrigger, this.optionHeight, this.panelHeight);
        }
    
        private _scrollToOption(
          this: MatAutocompleteTrigger,
          optionHeight: number,
          panelHeight: number,
        ): void {
          const index = this.autocomplete._keyManager.activeItemIndex || 0;
          const labelCount = _countGroupLabelsBeforeOption(
            index,
            this.autocomplete.options,
            this.autocomplete.optionGroups
          );
          if (index === 0 && labelCount === 1) {
            this.autocomplete._setScrollTop(0);
          } else {
            const newScrollPosition = _getOptionScrollPosition(
              index + labelCount,
              optionHeight,
              this.autocomplete._getScrollTop(),
              panelHeight
            );
            this.autocomplete._setScrollTop(newScrollPosition);
          }
      }
    }
    
    • 所以,我们使用_scrollToOption 方法的“原始”代码。我们只做一件事——避免使用常量:AUTOCOMPLETE_OPTION_HEIGHTAUTOCOMPLETE_PANEL_HEIGHT
    • 我们添加了两个输入 optionHeightpanelHeight 而不是这些常量
    • 作为新输入的默认值,我们使用 AUTOCOMPLETE_OPTION_HEIGHTAUTOCOMPLETE_PANEL_HEIGHT 的值
    步骤 2.2。添加指令和添加输入

    现在我们可以修改我们的模板并添加新指令和添加输入。

    <form class="example-form">
      <mat-form-field class="example-full-width">
        <input type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto" matAutocompleteTriggerAccessor [optionHeight]="24">
        <mat-autocomplete #auto="matAutocomplete">
          <mat-option *ngFor="let option of options" [value]="option">
            {{option}}
          </mat-option>
        </mat-autocomplete>
      </mat-form-field>
    </form>
    

    注意。我们的指令matAutocompleteTriggerAccessor 和输入optionHeight 应该附加到&lt;input&gt;,而不是&lt;mat-autocomplete&gt;

    仅此而已。现在一切正常。

    这是一个完整的解决方案:https://stackblitz.com/edit/angular-cn4ox8

    【讨论】:

      猜你喜欢
      • 2020-12-03
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      • 1970-01-01
      • 2019-03-24
      • 2019-03-02
      相关资源
      最近更新 更多