web-dev-qa-db-fra.com

bootstrap 4 in Angular 2 ne fonctionne pas)

J'ai suivi ce qui suit pour installer bootstrap 4 dans mon projet Angular 2 project: Réponse acceptée, après les premiers 1,2,3 et 4) étapes

Cependant, lorsque j'ajoute le HTML suivant à mon composant d'en-tête:

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

Comme vous pouvez le voir, c'est une liste déroulante en gros, lorsque je clique sur la liste déroulante, la page est actualisée, à la place, elle n'affiche pas l'option de "déconnexion".

C'est mon angular-cli.json section styles:

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

Et à l'intérieur de mon module Angular 2:

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

J'importe ensuite NgbModule dans la section des importations.

J'ai clairement manqué quelque chose, quelqu'un peut-il faire la lumière sur ce que c'est peut-être exactement?

12
Code Ratchet
  1. Veuillez installer ng-bootstrap à partir de ce lien Mise en route avec la commande suivante:

    npm `install --save @ng-bootstrap/ng-bootstrap`
    
  2. Importez-le sur app.module.ts comme

    import `{NgbModule} from '@ng-bootstrap/ng-bootstrap';` 
    
  3. Importer sur

    imports:[
       NgbModule.forRoot(),
    ]
    
  4. Ajouter ngbDropdown dans la liste déroulante

  5. Ajouter ngbDropdownToggle dans la liste déroulante Basculer DOM

  6. Ajouter ngbDropdownMenu dans le menu déroulant DOM

                <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

Variation sur @VictorLuchian pour les plus récents BS4 beta, il semble que la classe 'show' doit également être ajoutée dans le menu déroulant. Cette version comprend un clic à l'extérieur de la fermeture au lieu de la souris

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

Certains plugins et composants CSS dépendent d'autres plugins. Si vous incluez des plugins individuellement, assurez-vous de vérifier ces dépendances dans les documents. Notez également que tous les plugins dépendent de jQuery (cela signifie jQuery doit être inclus avant les fichiers de plugin ).

Dans .angular-cli.json ajoutez les lignes suivantes à la section des scripts:

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

Définition de la caisse ici

7
Hidayt Rahman

Comme l'a dit Andrien, vous pouvez simplifier le code comme ceci.

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

Exemple de code StackBliz Link

Tout d'abord Bootstrap 3 & 4 Les classes d'état actives déroulantes sont différentes

  1. Dans Boostrap 3: Dans l'état déroulant ouvert; L'élément parent .dropdown-toggle est ajouté ' open' Classe CSS

  2. Où, comme dans Boostrap 4, utilisez la classe CSS " show" Dans le menu déroulant ouvert. Ici, l'élément parent de l'élément .dropdown-toggle et l'élément frère suivant avec la classe CSS .dropdown-menu sont ajoutés " show" css Class

Par conséquent, pour que la liste déroulante boostrap 4 fonctionne avec angular 4, nous allons créer une nouvelle classe de directive angular et l'ajouter à la liste déroulante boostrap dans le modèle angular

Étape 1 - Créez une nouvelle directive angular dans 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;
    }
  }

}

Étape 2: Importez cette directive dans app.module.ts

import { NgBoostrapDropdownDirective } from './directives/ng-boostrap-dropdown.directive';

@NgModule({

  declarations: [ AppComponent, NgBoostrapDropdownDirective ],

})

Étape 3: Appliquer la directive dans le modèle en utilisant 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>

Exemple de code StackBliz Link

1
Rahul Talar

Inspiré par la première version de Rahul Talar (Étape 1 - Nouvelle caisse angular dans ng-boostrap-dropdown.directive.ts), j'ai fait quelques similaires en utilisant Rendere2

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

Avec Angular 8 et Bootstrap 4.2 c'est la solution de travail que j'utilise:

1- J'ai d'abord créé une directive personnalisée. Ce qu'il fait, c'est écouter l'événement au clic du conteneur déroulant et basculer la classe .show de l'élément .dropdown-menu (comportement standard de Bootstrap 4). De plus, cela fermera le menu déroulant s'il y a un clic partout ailleurs sur le document.

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- Une fois votre directive créée et enregistrée. Assurez-vous d'appliquer la directive à l'élément déroulant, comme dans cet exemple:

<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

j'ai utilisé une approche différente pour obtenir une liste déroulante sur la barre de navigation collpased.

ÉTAPE 1 Ajouter un événement de clic sur le bouton bascule de la barre de navigation

<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: implémenter la fonction à l'intérieur du composant Navbar.ts (le modèle html ci-dessus est utilisé dans le composant navbar)

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

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

Étape basé sur le bouton bascule de la barre de navigation, cliquez sur ajouter une classe show (bootstrap 4) ou open pour la précédente bootstrap versions. nous pouvons utiliser la directive ngClass pour cela

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

Flux de travail

Le bouton bascule de la barre de navigation sera visible lorsque la barre de navigation se réduira pour des résolutions plus petites

en gérant l'événement de clic de bouton, nous pouvons définir un indicateur pour vérifier si le bouton a cliqué ou non

Sur la base de ce drapeau, nous lierons la classe css show à navabr div en utilisant la directive ngClass

0
Lijo

Quelqu'un a créé une nouvelle version de la bibliothèque de modèles spécialement conçue pour Angular 2+. Selon le site Web, elle a été développée par ng-team, bien que le lien qu'il donne obtienne une réponse 404. Il fonctionne, cependant, et je l'ai utilisé à plusieurs endroits tout au long de mon projet actuel. Il vous suffira de récupérer la bibliothèque avec npm. Toutes les instructions sont sur ce site:

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

Cette page vous montre toutes les instructions d'installation et d'utilisation dont vous avez besoin pour commencer. J'espère que ça aide!

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

J'utilise un thème qui n'est pas construit pour Angular et il contient un bootstrap classique, j'ai eu le même problème et corrigé en modifiant le fichier bootstrap.js.

Le problème est que bootstrap écoutez les événements avec $ (document) .on et le problème est dans la partie "document".

Dans mon fichier bootstrap c'est la ligne 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();
  });

Remplacez $ (document) par $ ("body") et cela fonctionnera.

 $("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

Le CSS doit être dans le <head></head> tag.
Je cite du bootstrap

Copiez-collez la feuille de style <link> Dans votre <head> avant toutes les autres feuilles de style pour charger notre CSS.

Je continue de citer

Ajoutez nos plugins JavaScript, jQuery et Tether vers la fin de vos pages, juste avant la balise de fermeture. Assurez-vous de placer jQuery et Tether en premier, car notre code dépend d'eux.

Assurez-vous que vous disposez de cette manière voici le lien vers la documentation bootstrap où j'obtiens ces citations https://v4-alpha.getbootstrap.com/getting-started/introduction /

et vérifiez cette réponse dans le message que vous partagez le lien https://stackoverflow.com/a/39809447/3284537

0
Emiliano