web-dev-qa-db-ja.com

bootstrap 4 in Angular 2ドロップダウンが機能しない

私はbootstrap 4をmy Angular 2プロジェクトにインストールするために以下に従いました: Accepted Answer、after the first 1、 2,3および4ステップ

ただし、次の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">[email protected]</a>
            <div class="dropdown-menu" aria-labelledby="nav-dropdown">
                <a href="#" class="dropdown-item">Sign Out</a>
            </div>
        </li>
    </ul>
</div>

基本的にドロップダウンを見ることができるように、ドロップダウンをクリックするとページが更新され、代わりに「サインアウト」オプションが表示されません。

これは私の angular-cli.jsonスタイルセクション:

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

そして、私のAngular 2モジュール:

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

次に、NgbModuleをインポートセクションにインポートします。

私は明らかに何かを見逃しましたが、誰かがそれを正確に照らすことができますか?

12
Code Ratchet
  1. このリンクからng-bootstrapをインストールしてください Getting Started 次のコマンドで:

    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. ドロップダウンTOM DOMにngbDropdownToggleを追加

  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>
    
13

最新の@VictorLuchianのバリエーションBS4ベータ、ドロップダウンメニューにも「show」クラスを追加する必要があるようです。このバージョンには、mouseoutの代わりにclose outsideのクリックが含まれます

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')
    }
}
}
12
Adrien Pavillet

一部のプラグインとCSSコンポーネントは他のプラグインに依存しています。プラグインを個別に含める場合は、ドキュメントでこれらの依存関係を確認してください。また、すべてのプラグインはjQueryに依存していることに注意してください(これは、プラグインファイルの前にjQueryを含める必要があることを意味します)。

.angular-cli.jsonスクリプトセクションに次の行を追加します。

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

ここでチェックアウト定義

7
Hidayt Rahman

Andrienが言ったように、このようなコードを単純化できます。

constructor(private _el: ElementRef) { }

@HostBinding('class.show') isOpen = false;

@HostListener('click') toogleOpen() {
    this.isOpen = !this.isOpen;
    this._el.nativeElement.querySelector('.dropdown-menu').classList.toggle('show')
}
5
dpolicastro

これが機能するためには、ドロップダウンディレクティブを追加する必要があります。ディレクティブは次のようになります。

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 >
3
Victor Luchian

サンプルコードStackBlizリンク

まず、Bootstrap 3および4ドロップダウンのアクティブ状態のクラスは異なります

  1. Boostrap 3の場合:ドロップダウンオープン状態。 .dropdown-toggle親要素が追加された 'open' CSSクラス

  2. Boostrap 4のように、「show」CSSクラスのドロップダウンオープン状態を使用します。ここで、.dropdown-toggle要素の親要素とCSSクラス.dropdown-menuを持つ次の兄弟要素が追加されます。「show」cssクラス

したがって、angular 4でboostrap 4ドロップダウンを機能させるために、新しいangularディレクティブクラスを作成し、angularテンプレートのboostrapドロップダウンに追加します。

ステップ1-ng-boostrap-dropdown.directive.tsの新しいangularディレクティブを作成します

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>

サンプルコードStackBlizリンク

1
Rahul Talar

Rahul Talarの最初のバージョンに触発された(ステップ1-ng-boostrap-dropdown.directive.tsの新しいangular指令の作成)

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

@Directive({
  selector: '[appDropdown]'
})
export class AppDropdownDirective implements OnInit {
  private isShow = false;
  private classShow = 'show';
  private parentNode: HTMLElement;
  private siblingNode: HTMLElement;

  constructor(private elementRef: ElementRef, private renderer: Renderer2) {}

  ngOnInit() {
    this.parentNode = this.renderer.parentNode(this.elementRef.nativeElement);
    this.siblingNode = this.renderer.nextSibling(this.elementRef.nativeElement);
  }

  @HostListener('click') open() {
    this.isShow = !this.isShow;
    if (this.isShow) {
      this.addClass();
    } else {
      this.removeClass();
    }
  }

  @HostListener('document:click', ['$event']) clickout(event) {
    if (this.elementRef.nativeElement !== event.target && this.isShow) {
      this.removeClass();
      this.isShow = false;
    }
  }

  private addClass() {
    this.renderer.addClass(this.parentNode, this.classShow);
    this.renderer.addClass(this.siblingNode, this.classShow);
  }

  private removeClass() {
    this.renderer.removeClass(this.parentNode, this.classShow);
    this.renderer.removeClass(this.siblingNode, this.classShow);
  }
}
1
oleg gabureac

Angular 8 and Bootstrap 4.2これは私が使用している作業ソリューションです:

1-最初に、カスタムディレクティブを作成しました。これは、ドロップダウンコンテナのon clickイベントをリッスンし、.dropdown-menu要素の.showクラスを切り替えます(ブートストラップ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-ディレクティブを作成して登録したら。この例のように、必ずディレクティブをドロップダウン要素に適用してください。

<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>
0
Dayron Gallardo

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');
      }
    }
0
Prakash Khadka

折りたたまれたnavbarでドロップダウンを取得するために、別のアプローチを使用しました。

ステップ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>

Step2: Navbar component.ts内で関数を実装します(上記のnavbar htmlテンプレートはnavbarコンポーネント内で使用されます)

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

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

ステップ navbarトグルボタンのクリックに基づいてクラスを追加show(bootstrap 4)またはopen for previous bootstrapバージョン。これにはngClassディレクティブを使用できます

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

ワークフロー

解像度が小さい場合、ナビゲーションバーが折りたたまれるとナビゲーションバーのトグルボタンが表示されます

ボタンクリックイベントを処理することにより、ボタンがクリックされたかどうかを確認するためのフラグを1つ設定できます。

このフラグに基づいて、ngClassディレクティブを使用してcssクラスshowをnavabr divにバインドします

0
Lijo

誰かがAngular 2+向けに特別に設計したテンプレートライブラリの新しいバージョンを作成しました。ウェブサイトによると、ng-teamによって開発されましたが、リンクは404応答を受け取ります。ただし、現在のプロジェクト全体で複数の場所で使用していますが、npmを使用してライブラリを取得する必要があります。

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

そのページには、開始するために必要なすべてのインストールおよび使用手順が表示されます。これがお役に立てば幸いです!

0
Grungondola
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');
    }
  }

}
0
Pradyumna H A

Angular向けにビルドされていないテーマを使用しており、クラシックブートストラップが含まれています。同じ問題があり、bootstrap.jsファイルを変更することで修正しました。

問題はbootstrap= $(document).onでイベントをリッスンし、問題は「ドキュメント」部分にあります。

私の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();
  });

$(document)を$( "body")に変更すると動作します。

 $("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();
      });
0
Dimash

CSSは<head></head>タグ内にある必要があります。
ブートストラップから引用

スタイルシート<link>を他のすべてのスタイルシートの前に<head>にコピーして貼り付け、CSSを読み込みます。

引用を続ける

JavaScriptプラグイン、jQuery、およびTetherをページの終わり近く、終了タグの直前に追加します。コードはそれらに依存しているため、jQueryとTetherを最初に配置してください。

この方法で、bootstrapドキュメンテーションへのリンクがあることを確認してください。ここでは、この引用符を取得します はじめに/紹介/

リンクを共有する投稿でこの回答を確認してください https://stackoverflow.com/a/39809447/3284537

0
Emiliano