Как установить ширину выпадающего меню ngb, унаследованного от родительского выпадающего списка ngb, добавляемого к телу?

#html #angular #ng-bootstrap

#HTML #angular #ng-bootstrap

Вопрос:

Поскольку я должен использовать свойство

контейнер ="тело"

-> https://github.com/ng-bootstrap/ng-bootstrap/issues/1012

Мой выпадающий список прикреплен к телу (поправьте меня, если я ошибаюсь …).
Таким образом, это означает, что я не могу наследовать ширину от parent (ngbDropdown)-> ngbDropdownMenu.
Как я могу установить одинаковую ширину для выпадающего меню и кнопки??

NGB DROPDOWN с шириной: наследуется, но без свойства container=»body»

NGB DROPDOWN с шириной: наследуется, но со свойством container=»body»

Итак, мне нужно свойство container =»body», но я все еще хочу унаследовать ширину от button

Комментарии:

1. очень сложно понять вопрос в его нынешнем виде — можете ли вы предоставить пример MVC?

2. Изображения прикреплены

Ответ №1:

У меня есть решение для этого! Это комбинация нескольких методов. Я добавил некоторый код Typescript, который прослушивает openChange событие, генерируемое выпадающим списком. В это время я выбираю ширину hostElement , которая является триггером выпадающего списка. Я использую это, чтобы установить ширину .dropdown , которая была добавлена к body. Теперь будет работать мой CSS, который устанавливает .dropdown-menu ширину на 100%. К сожалению, это вызывает кратковременную вспышку, когда пользователь может видеть выпадающий список нормальной ширины, прежде чем он изменится на 100% ширины триггера. Чтобы исправить это, я использую некоторый CSS для управления непрозрачностью .dropdown-menu .

1) Перехватите (openChange) событие ngb Dropdown:

 <div
    ngbDropdown #dropdown="ngbDropdown" container="body"
    #hostElement (openChange)="fixDropdownWidth(hostElement)">
  

Я использую переменную шаблона для получения ссылки на hostElement и передаю этот элемент в качестве параметра моей функции fixDropdownWidth() в моем компоненте:

2) Исправить функцию компонента:

     fixDropdownWidth(hostElement: HTMLDivElement) {
        setTimeout(() => {
            let bodyDD: HTMLDivElement[] = <HTMLDivElement[]>Array.from(this._document.body.children).filter((child: HTMLDivElement) => child.className.indexOf('dropdown') >= 0);
            if (bodyDD amp;amp; bodyDD.length) {
                this._renderer.setStyle(bodyDD[0], 'width', hostElement.clientWidth   'px');
                this._renderer.addClass(bodyDD[0].children[0], 'fixed');
            }
        }, 0);
    }
  

Я должен использовать setTimeout() здесь, потому что .dropdown на самом деле оно еще не добавлено в DOM.

3) Для этого используется Angular Renderer2, который необходимо ввести в ваш конструктор вместе с Angular @DOCUMENT :

     constructor(@Inject(DOCUMENT) private _document: any, private _renderer: Renderer2) { }
  

Вам нужно будет добавить некоторые import s в ваш компонент для этих:

 import { Renderer2 } from '@angular/core';
import { DOCUMENT } from '@angular/common';
  

4) Последняя часть головоломки — это CSS, который по умолчанию делает .dropdown-menu непрозрачность 0, пока ширина не будет «исправлена». Смотрите здесь также, min-width: 100% который делает выпадающий список той же ширины, что и триггер с помощью CSS.

 body > .dropdown > .dropdown-menu {
    min-width: 100%;
    opacity: 0;
    transition: opacity 150ms ease-in-out;
    amp;.fixed {
        opacity: 1;
    }
}
  

Итак, все вместе, что произошло?

  1. Мы подключились к событию openChange, генерируемому ngbDropdown.
  2. В то время мы использовали ширину hostElement и установили для .dropdown-menu контейнера .dropdown такую же ширину, таким образом, наше CSS-правило min-width: 100% будет работать
  3. Поскольку dropdown-menu индикатор коротко мигает, мы уменьшили непрозрачность до нуля.
  4. В нашей процедуре исправления мы устанавливаем класс «fixed», который отображает выпадающий список с помощью opacity: 1 после того, как ширина была установлена правильно.

Последнее, что нужно упомянуть, это то, что я добавил проблему с Github для этого:https://github.com/ng-bootstrap/ng-bootstrap/issues/3523 Запрошено, чтобы платформа ng-bootstrap установила ширину hostElement, чтобы нам не пришлось выполнять этот обходной путь.