如何设置从父ngb Dropdown继承的ngb Dropdown菜单的宽度追加到正文?

时间:2019-04-09 14:45:20

标签: html angular ng-bootstrap


由于我必须使用属性

container="body"
-> https://github.com/ng-bootstrap/ng-bootstrap/issues/1012
我的下拉列表附加到身体上(如果我错了,请纠正我...)。
因此,这意味着我无法从父(ngbDropdown)-> ngbDropdownMenu继承宽度。
如何为下拉菜单和按钮设置相同的宽度?

NgbDropdown with width: inherit but without property container="body"

ngbDropdown with width: inherit but with property container="body"

所以我需要属性container =“ body” 但仍然想继承按钮的宽度

1 个答案:

答案 0 :(得分:0)

我有解决方案!它是几种技术的组合。我添加了一些Typescript代码,以侦听Dropdown发出的openChange事件。那时,我抓住了hostElement的宽度,它是下拉菜单的触发器。我用它来设置附加到正文的.dropdown的宽度。现在,我的CSS将起作用,它将.dropdown-menu的宽度设置为100%。不幸的是,这会引起短暂的闪烁,用户可以在正常宽度下看到下拉列表,然后将其更改为触发器宽度的100%。为了解决这个问题,我使用了一些CSS来控制.dropdown-menu的不透明度。

1)钩住了ngbDropdown的(openChange)事件:

<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 && 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到组件:

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;
    &.fixed {
        opacity: 1;
    }
}

现在在一起,发生了什么事?

  1. 我们利用了ngbDropdown发出的openChange事件。
  2. 那时我们抓住了hostElement的宽度,并将.dropdown-menu的容器.dropdown设置为相同的宽度,这样我们的min-width: 100%的CSS规则就会起作用
  3. 由于dropdown-menu短暂闪烁,我们将不透明度设为零。
  4. 在我们的修复程序中,我们设置了一个“固定”类,该类在正确设置宽度后会显示opacity: 1下拉列表。

最后要提到的是我为此添加了一个Github问题: https://github.com/ng-bootstrap/ng-bootstrap/issues/3523 请求让ng-bootstrap框架设置hostElement的宽度,这样我们就不必执行此解决方法。