Панель mat-autocomplete должна быть той же ширины, что и ввод хоста, или шире в зависимости от содержимого.

У меня есть угловой компонент дерева автозаполнения, и у меня проблема с шириной панели автозаполнения.

У меня есть два требования, которые я могу решить индивидуально, но не вместе:

  • Панель должна увеличиваться, когда контент становится шире панели. Я использовал [panelWidth] = "auto" для этого, и он отлично работает.
  • Панель должна иметь минимальную ширину входа хоста. Для этого также можно использовать panelWidth, но тогда я теряю функциональность в первом пункте.

Из Изменить ширину автозаполнения мата?) я увидел, что могу использовать [panelWidth] = "auto".

Я знаю, что могу использовать стили css .mat-autocomplete-panel{min-width: "300px"}, но не знаю, как получить ширину конкретного ввода.

Поэтому я обратился к javascript. Я видел в документации, что AutocompletePanel предоставляет панель ElementRef, но это значение кажется неопределенным независимо от того, что я делаю? Правильный ли способ получить это значение с помощью @ViewChild? У меня есть следующий код, который запускается при событии opened.

<mat-autocomplete #autocomplete (opened)="opened()" [panelWidth]="auto" #auto="matAutocomplete">
@ViewChild("auto") autocomplete: MatAutocomplete;
@ViewChild("autoTreeInput") autoTreeInput: ElementRef;

  opened = () => {
    setTimeout(()=>{

    let p = this.autocomplete.panel?.nativeElement; //always null because panel is undefi
    console.log("opened", p, this.autocomplete);
    if (!p ) return
    p.style.minWidth =
      this.autoTreeInput.nativeElement.getBoundingClientRect().width + "px";
    },1000)
  };

Stackblitz


person Pieter Buys    schedule 19.01.2021    source источник


Ответы (2)


Я просмотрел вам пример stackblitz.

Похоже, это скорее проблема css.

Попробуйте это с autocomplete-simple-example.css файлом

.example-form {
  min-width: 150px;
  // max-width <-- remove it to use 100% of width
  width: 100%;
}

.example-full-width {
  width: 100%; // add this to use all width.
  transition: width 0.5s ease;
}
.mat-focused {
  width: 270px;
}

Вот рабочий пример: stackblitz

Изменить

Вы можете добавить любой действующий CSS в width css. Таким образом, добавлено calc(100% - 60%), чтобы зафиксировать его так же, как ввод

.example-form {
  min-width: 150px;
  width: 100%;
}

.example-full-width {
  width: 100%;
  transition: width 0.5s ease;
}
.mat-focused {
  width: 100%;
}
<mat-autocomplete (opened)="opened()" panelWidth="calc(100% - 60px)" </mat-autocomplete>

Рабочий пример

person Luis Reinoso    schedule 19.01.2021
comment
Поэтому мне нужно, чтобы панель была той же ширины, что и ‹input›, или больше, если контент становится шире. И в вашем примере этого, похоже, не происходит - person Pieter Buys; 19.01.2021
comment
Пожалуйста, ознакомьтесь с моим редактированием. - person Luis Reinoso; 19.01.2021
comment
К сожалению, все еще нет кубиков. panelWidth = calc (100% - 60px) сделает панель 100% окна, а не 100% ввода, поэтому изменение размера ввода не повлияет на ширину панели. Кроме того, если для параметра panelWidth не задано значение auto, ширина panelWidth не будет увеличиваться по мере увеличения содержимого. Пожалуйста, обратите внимание на оба требования в моем вопросе, поскольку я знаю способы достижения каждого в отдельности, но не вместе. - person Pieter Buys; 20.01.2021

Элемент панели elementRef появляется после (не включенного) события opened. В частности, после добавления панели в DOM. Так что просто добавив setTimeout, в котором я получаю, что элемент работает. К сожалению, это означает, что элемент отображается с неправильной шириной, а затем переходит к ширине ввода.

Возможно, есть лучшее решение, но я сейчас к этому и прибегаю.

 opened = ()=> {
    let inputWidth = this.autoInput.nativeElement.getBoundingClientRect().width
    setTimeout(()=>{
      let panel = this.autocomplete.panel?.nativeElement;

      if (!panel ) return
      panel.style.minWidth = inputWidth + "px";
    })
  }

Рабочий stackblitz

person Pieter Buys    schedule 20.01.2021