Angular 2下拉列表中的bootstrap 4无法正常工作

时间:2016-12-24 23:04:57

标签: twitter-bootstrap angular

我已按照以下说明将bootstrap 4安装到我的Angular 2项目中:Accepted Answer, following the first 1,2,3 and 4 steps

但是,当我将以下HTML添加到我的标题组件时:

<nav class="navbar-dark bg-inverse">
<div class="container">
    <a href="#" class="navbar-brand"></a>
    <ul class="nav navbar-nav float-xs-right">
        <li class="nav-item dropdown">
            <a href="#" class="nav-link dropdown-toggle" id="nav-dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">SomeEmail@hotmail.com</a>
            <div class="dropdown-menu" aria-labelledby="nav-dropdown">
                <a href="#" class="dropdown-item">Sign Out</a>
            </div>
        </li>
    </ul>
</div>

正如您可以看到它的基本下拉菜单,当我点击下拉列表时,页面会刷新,而不会显示“退出”#39;&#39;选项。

这是我的angular-cli.json样式部分:

"styles": [
  "styles.css",
  "../node_modules/bootstrap/dist/css/bootstrap.min.css"
],    

在我的Angular 2模块中:

import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

然后我将NgbModule导入导入部分。

我显然错过了一些东西,有人可以说明它可能究竟是什么吗?

14 个答案:

答案 0 :(得分:11)

@VictorLuchian对最新 BS4 beta 的变化,似乎&#39;显示&#39; class也需要添加到下拉菜单中。 此版本包括外部关闭而非鼠标输出

import { Directive,HostListener,HostBinding, ElementRef } from '@angular/core'; 
@Directive({
  selector: '[customdropdown]'
})
export class CustomDropdownDirective {

private isOpen: boolean =false;
constructor(private _el: ElementRef) { 

}

@HostBinding('class.show') get opened() {
    return this.isOpen;
}
@HostListener('click') open() {
    this.isOpen = true;
    this._el.nativeElement.querySelector('.dropdown-menu').classList.add('show')                
}
@HostListener('document:click', ['$event.target']) close (targetElement) {
    let inside: boolean = this._el.nativeElement.contains(targetElement);
    if(!inside) {
        this.isOpen = false;
        this._el.nativeElement.querySelector('.dropdown-menu').classList.remove('show')
    }
}
}

答案 1 :(得分:11)

  1. 请使用以下命令从此链接Getting Started安装ng-bootstrap:

    npm `install --save @ng-bootstrap/ng-bootstrap`
    
  2. 将其导入app.module.ts

    import `{NgbModule} from '@ng-bootstrap/ng-bootstrap';` 
    
  3. 导入

    imports:[
       NgbModule.forRoot(),
    ]
    
  4. 在下拉列表中添加ngbDropdown

  5. 在下拉列表中添加ngbDropdownToggle切换DOM

  6. 在下拉菜单DOM

    上添加ngbDropdownMenu

                <li ngbDropdown  class="nav-item dropdown" >
                    <a ngbDropdownToggle class="nav-link dropdown-toggle"  href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                     Manage
                    </a>
                    <div ngbDropdownMenu  class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
                      <a class="dropdown-item" href="#">Save Data</a>
                      <a class="dropdown-item" href="#">Fetch Data</a>
    
                    </div>
                  </li>
              </ul>
    

答案 2 :(得分:7)

某些插件和CSS组件依赖于其他插件。如果您单独包含插件, 确保在文档中检查这些依赖项。另请注意,所有插件都依赖于 jQuery(这意味着 jQuery必须包含在插件文件之前)。

.angular-cli.json中,将以下行添加到脚本部分:

# version 4.x
  "scripts": [
    "../node_modules/jquery/dist/jquery.js",
    "../node_modules/bootstrap/dist/js/bootstrap.js",
  ]

Checkout definition here

答案 3 :(得分:3)

您需要添加一个下拉指令才能使其正常工作。 该指令如下所示:

import { Directive,HostListener,HostBinding } from '@angular/core'; 
@Directive({
selector: '[appcustomdropdown]'
})
export class CustomdropdownDirective {

constructor() { }

@HostBinding('class.open') get opened()
{
return this.isOpen;
}
@HostListener('click') open()
{
this.isOpen=true;
}
@HostListener('mouseleave') close()
{
this.isOpen=false;
}
private isOpen=false;
}

然后,您将添加如下属性:

<li class="nav-item dropdown" appcustomdropdown >

答案 4 :(得分:3)

就像Andrien所说的那样,您可以像这样简化代码。

dict

答案 5 :(得分:1)

Example Code StackBliz Link

首先是Bootstrap 3&amp; 4下拉活动状态类是不同的

  1. 在Boostrap 3中:处于下拉打开状态; .dropdown-toggle父元素添加了“打开”CSS类

  2. 在Boostrap 4中使用“显示”CSS类 在下拉开状态。这里.dropdown-toggle元素的父元素和CSS类.dropdown-menu的下一个兄弟元素添加了“显示”css类

  3. 因此,为了使用角度4进行boostrap 4下拉工作,我们将创建新的角度指令类并将其添加到角度模板中的boostrap下拉列表

    步骤1 - 在ng-boostrap-dropdown.directive.ts中创建新的角度指令

    import { Directive, HostListener, ElementRef } from '@angular/core';
    
    @Directive({
      selector: '[appNgBoostrapDropdown]'
    })
    export class NgBoostrapDropdownDirective {
    
      private isShow: boolean = false;
      private dropdownParentEl = this.elementRef.nativeElement.closest('.dropdown');
      constructor(private elementRef: ElementRef) { }
    
    
      @HostListener('click') open() {
        this.isShow = !this.isShow;
        if (this.isShow) {
          this.dropdownParentEl.classList.add('show');
          this.dropdownParentEl.querySelector(".dropdown-menu").classList.add('show');
        } else {
          this.dropdownParentEl.classList.remove('show');
          this.dropdownParentEl.querySelector(".dropdown-menu").classList.remove('show');
        }
      }
    
      @HostListener('document:click', ['$event'])
      clickout(event) {
        if (this.elementRef.nativeElement.contains(event.target) && this.isShow) {
          this.dropdownParentEl.classList.add('show');
          this.dropdownParentEl.querySelector(".dropdown-menu").classList.add('show');
        } else {
          this.dropdownParentEl.classList.remove('show');
          this.dropdownParentEl.querySelector(".dropdown-menu").classList.remove('show');
          this.isShow = false;
        }
      }
    
    }
    

    第2步:在app.module.ts中导入此指令

    import { NgBoostrapDropdownDirective } from './directives/ng-boostrap-dropdown.directive';
    
    @NgModule({
    
      declarations: [ AppComponent, NgBoostrapDropdownDirective ],
    
    })
    

    第3步:使用appNgBoostrapDropdown在模板中应用指令

    NAVIGATION : 
          <li class="nav-item dropdown" >
                <a class="nav-link dropdown-toggle" appNgBoostrapDropdown  href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
                <div class="dropdown-menu" aria-labelledby="dropdown01">
                  <a class="dropdown-item" href="#">Action</a>
                  <a class="dropdown-item" href="#">Another action</a>
                  <a class="dropdown-item" href="#">Something else here</a>
                </div>
              </li>
            </ul>
    
    BUTTON DROPDOWN : 
    
    <div class="dropdown">
      <button class="btn btn-secondary dropdown-toggle" appNgBoostrapDropdown type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        Dropdown button
      </button>
      <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
        <a class="dropdown-item" href="#">Action</a>
        <a class="dropdown-item" href="#">Another action</a>
        <a class="dropdown-item" href="#">Something else here</a>
      </div>
    </div>
    

    Example Code StackBliz Link

答案 6 :(得分:1)

受Rahul Talar的第一个版本(第1步-在ng-boostrap-dropdown.directive.ts中创建新的角度指令)的启发,我使用Rendere2做了类似的事情

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<ul id="tabsnav" class="nav nav-tabs hero-image-tabs">
    <li class="hero-img-1"><a href="#" data-toggle="tab" data-bg="img/bg-img-hero-2.jpg">Hero 1</a></li>
    <li class="hero-img-2"><a href="#" data-toggle="tab" data-bg="img/bg-img-hero-8.jpg">Hero 2</a></li>

</ul>

<header class="hero-section py-5 ">
    <div class="container py-5">
        <div class="row">
            <div class="col-md-12">
                <h1 class="display-4 text-white mt-4">Connecting Leaders. Inspiring Innovation.</h1>
            </div>
        </div>
    </div>
</header>

答案 7 :(得分:0)

CSS需要位于<head></head>标记中 我引用bootstrap

  

将样式表<link>复制粘贴到<head>之前   样式表加载我们的CSS。

我继续引用

  

在我们的最后添加我们的JavaScript插件,jQuery和Tether   页面,就在结束标记之前。一定要放置jQuery   和Tether首先,因为我们的代码依赖于它们。

确保你拥有这种方式 这里是引导文档的链接,我得到这个引号 https://v4-alpha.getbootstrap.com/getting-started/introduction/

并在帖子中查看您共享该链接的答案 https://stackoverflow.com/a/39809447/3284537

答案 8 :(得分:0)

有人为Angular 2+专门设计了新版本的模板库。据该网站称,它是由ng-team开发的,尽管它提供的链接得到了404响应。但它确实有效,而且我在当前项目的多个地方都使用过它。你只需要用npm拉入图书馆。所有说明都在本网站上:

http://valor-software.com/ngx-bootstrap/#/

该页面显示了入门所需的所有安装和使用说明。我希望这有帮助!

答案 9 :(得分:0)

我使用了一种不同的方法来获取下拉式导航栏。

第1步 在导航栏切换按钮

上添加点击事件
<button type="button" class="navbar-toggle" data-toggle="collapse" (click)="OnClik()" data-target="#myNavbar"

<强> HTML

    <nav class="navbar navbar-inverse">
  <div class="container-fluid">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" (click)="OnClik()" data-target="#myNavbar">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">WebSiteName</a>
    </div>
    <div class="collapse navbar-collapse " [ngClass]="{'show': buttontoggled}" id="myNavbar">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Home</a></li>
        <li class="dropdown">
          <a class="dropdown-toggle" data-toggle="dropdown" href="#">Page 1 <span class="caret"></span></a>
          <ul class="dropdown-menu">
            <li><a href="#">Page 1-1</a></li>
            <li><a href="#">Page 1-2</a></li>
            <li><a href="#">Page 1-3</a></li>
          </ul>
        </li>
        <li><a href="#">Page 2</a></li>
        <li><a href="#">Page 3</a></li>
      </ul>
      <ul class="nav navbar-nav navbar-right">
        <li><a href="#"><span class="glyphicon glyphicon-user"></span> Sign Up</a></li>
        <li><a href="#"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
      </ul>
    </div>
  </div>
</nav>

<强>步骤2: 实现里面的功能 Navbar component.ts(导航栏组件内部使用导航栏html模板)

import { Component} from '@angular/core';
    export class HeaderComponent  {
      buttontoggled:boolean:false;

    OnClik(){
      this.buttontoggled=!this.buttontoggled;
    }

第3步 基于导航栏切换按钮,单击添加类 show (bootstrap 4)或open以获取先前的引导版本。 我们可以使用ngClass指令

 <div class="collapse navbar-collapse " [ngClass]="{'show': buttontoggled}" id="myNavbar">

工作流程

当导航栏geting折叠为较小分辨率

时,将显示导航栏切换按钮

通过处理按钮点击事件,我们可以设置一个标志来检查按钮是否点击

基于这个标志我们会  我们将使用ngClass指令

将css类show绑定到navabr div

答案 10 :(得分:0)

我使用的主题不是为Angular构建的,它包含经典的引导程序,我有同样的问题并通过修改bootstrap.js文件来修复。

问题是引导程序使用$(document).on监听事件,而问题出在&#34; document&#34;一部分。

在我的bootstrap文件中,它是第18001行

 /**
   * ------------------------------------------------------------------------
   * Data Api implementation
   * ------------------------------------------------------------------------
   */


  $(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
    event.preventDefault();
    event.stopPropagation();

    Dropdown._jQueryInterface.call($(this), 'toggle');
  }).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {
    e.stopPropagation();
  });

将$(文档)更改为$(&#34; body&#34;)并且它会起作用。

 $("body").on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
        event.preventDefault();
        event.stopPropagation();

        Dropdown._jQueryInterface.call($(this), 'toggle');
      }).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {
        e.stopPropagation();
      });

答案 11 :(得分:0)

navbar.component.html

<li class="nav-item dropdown show" appDropdown>
        <a class="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          Categories
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdown">
          <a routerLink="yourLInk1" class="dropdown-item">Item 1</a>
          <a routerLink="yourLInk2" class="dropdown-item">Item 2</a>
          <a routerLink="yourLInk3" class="dropdown-item">Item 3</a>
          <a routerLink="yourLInk4" class="dropdown-item">Item 4</a>
          <div class="dropdown-divider"></div>
          <a routerLink="yourLInk5" class="dropdown-item">Item 5</a>
        </div>
      </li>

dropdown.directive.ts

import { Directive, HostBinding, HostListener, ElementRef } from '@angular/core';

    @Directive({
      selector: '[appDropdown]'
    })
    export class DropdownDirective {
      constructor(private elementRef: ElementRef) { }

      private dropdownParentEl = this.elementRef.nativeElement.closest('.dropdown');

      @HostListener('mouseenter') toggleOpen(){
        this.dropdownParentEl.querySelector(".dropdown-menu").classList.add('show');
      }
      @HostListener('mouseleave') toggleClose(){
        this.dropdownParentEl.querySelector(".dropdown-menu").classList.remove('show');
      }

      @HostListener('click') toogleOpen() {
          this.dropdownParentEl.querySelector(".dropdown-menu").classList.toggle('show');
      }
    }

答案 12 :(得分:0)

import { Directive, HostListener, HostBinding, ElementRef } from '@angular/core';

@Directive({
  selector: '[appDropdown]'
})
export class DropdownDirective {
  constructor(private _el: ElementRef) { 
  }
  @HostBinding('class.show') isOpen = false;
  @HostListener('click') toggleOpen(){
    this.isOpen=!this.isOpen;
    if(this.isOpen){
      this._el.nativeElement.querySelector('.dropdown-menu').classList.add('show'); 
    }
    else{
      this._el.nativeElement.querySelector('.dropdown-menu').classList.remove('show');
    }
  }

}

答案 13 :(得分:0)

对于Angular 8和Bootstrap 4.2,这是我正在使用的有效解决方案:

1-首先,我创建了一个自定义指令。它的作用是侦听下拉容器的on click事件,并切换.dropdown-menu元素的.show类(Bootstrap 4标准行为)。另外,如果在文档上其他任何地方都单击,它将关闭下拉菜单。

import {Directive, ElementRef, HostBinding, HostListener, OnInit} from '@angular/core';

@Directive({
  selector: '[appDropdown]'
})
export class DropdownDirective implements OnInit {
  dropDownMenu: HTMLElement;
  @HostListener('document:click', ['$event']) toggleOpen(event: Event) {
    if ( this.dropDownButton.nativeElement.contains(event.target) ) {
      this.dropDownMenu.classList.toggle('show');
    } else {
      this.dropDownMenu.classList.remove('show');
    }
  }

  constructor(private dropDownButton: ElementRef) { }

  ngOnInit(): void {
    this.dropDownMenu = this.dropDownButton.nativeElement.querySelector('.dropdown-menu');
  }
}

2-一旦您的指令创建并注册。请确保将指令应用于dropdown元素,例如在此示例中:

<div class="btn-group" appDropdown>
    <button type="button" class="btn btn-primary dropdown-toggle">Dropdown menu<span class="caret"></span></button>
    <ul class="dropdown-menu">
        <li class="dropdown-item"><a href="#">Item One</a></li>
        <li class="dropdown-item"><a href="#">Item Two</a></li>
        <li class="dropdown-item"><a href="#">Item Three</a></li>
    </ul>
</div>