Bootstrap 4 в папке Angular 2 не работает

Я выполнил следующее, чтобы установить bootstrap 4 в мой проект Angular 2: Принятый ответ, после первых 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 в раздел импорта.

Я явно что-то пропустил, может кто-то пролить свет на то, что это может быть точно?

Ответ 1

  1. Пожалуйста, установите 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 в раскрывающемся ngbDropdown

  5. Добавить ngbDropdownToggle в раскрывающемся ngbDropdownToggle Toggle DOM

  6. Добавьте ngbDropdownMenu в выпадающее меню 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>
    

Ответ 2

Вариация на @VictorLuchian для новейшей BS4 beta​​strong > , кажется, что класс show также нужно добавить в раскрывающемся меню. Эта версия включает в себя щелчок за пределами закрытия, а не мыши.

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')
    }
}
}

Ответ 3

Некоторые плагины и компоненты CSS зависят от других плагинов. Если вы включаете плагины по отдельности, обязательно проверьте эти зависимости в документации. Также обратите внимание, что все плагины зависят от jQuery (это означает, что jQuery должен быть включен перед файлами плагинов).

В .angular-cli.json добавьте следующие строки в раздел скриптов:

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

Оформить заказ здесь

Ответ 4

Как сказал Андриен, вы можете упростить код следующим образом.

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

Вам нужно будет добавить директиву выпадающего списка, чтобы это работало. Директива выглядит так:

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 >

Ответ 6

Пример кода StackBliz Ссылка

Во-первых, Bootstrap 3 и 4. Разные классы активного состояния отличаются

  1. В Boostrap 3: в раскрывающемся раскрытом состоянии; Добавлен родительский элемент .dropdown-toggle " открытый " класс CSS

  2. Где, как в Boostrap 4, использовать CSS-класс " show " в выпадающем открытом состоянии. Здесь добавлен родительский элемент элемента .dropdown-toggle и следующий элемент с классом CSS.dropdown-menu " show " css Class

Следовательно, чтобы сделать раскрывающийся список boostrap 4 работающим с angular 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>

Пример кода StackBliz Ссылка

Ответ 7

Вдохновленный первой версией Рахула Талара (Шаг 1 - Создайте новую угловую директиву в ng-boostrap-dropdown.directive.ts), я сделал несколько подобных, используя 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);
  }
}

Ответ 8

CSS должен находиться в теге <head></head>.
Я цитирую из бутстрапа

Скопируйте в таблицу стилей <link> в свой <head>, прежде чем все остальные stylesheets для загрузки нашего CSS.

Я продолжаю цитирование

Добавьте наши плагины JavaScript, jQuery и Tether в конце вашего страниц, перед закрывающим тегом. Обязательно поместите jQuery и Tether, так как наш код зависит от них.

Убедитесь, что у вас таким образом вот ссылка на документацию бутстрапа, где я получаю эти цитаты https://v4-alpha.getbootstrap.com/getting-started/introduction/

и проверьте этот ответ в сообщении, в котором вы делитесь ссылкой fooobar.com/questions/49172/...

Ответ 9

Кто-то создал новую версию библиотеки шаблонов, специально предназначенную для Angular 2+. Согласно веб-сайту, он был разработан командой ng, хотя ссылка, которую она дает, получает ответ 404. Это действительно работает, и я использовал его в нескольких местах в течение всего моего текущего проекта. Вам просто нужно забрать библиотеку с помощью npm. Все инструкции находятся на этом веб-сайте:

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

На этой странице показаны все инструкции по установке и использованию, которые вам нужно приступить к работе. Надеюсь, это поможет!

Ответ 10

Я использовал другой подход для того, чтобы получить падение на сложенном 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>

Шаг 2: реализовать функцию внутри Navbar component.ts(Над шаблоном navbar html используется внутри компонента navbar)

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

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

Шаг 3 на основе кнопки переключения навигатора нажмите кнопку add show show (bootstrap 4) или open для предыдущих версий начальной загрузки. мы можем использовать директиву ngClass для этого

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

Рабочий поток

Кнопка переключения Navbar будет видна, когда сбой при входе в навигационную панель для меньших разрешений

обрабатывая событие нажатия кнопки, мы можем установить один флаг, чтобы проверить, не нажата ли кнопка или нет

На основании этого флага мы будем  мы свяжем показ класса css с navabr div, используя директиву ngClass

Ответ 11

Я использую тему, которая не является сборкой для Angular, и она содержит классический загрузчик, у меня была та же проблема и исправлена путем изменения файла bootstrap.js.

Проблема заключается в том, что загружаются события прослушивания с $ (document).on, а проблема в части "document".

В моем файле начальной загрузки это строка 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();
      });

Ответ 12

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

Ответ 13

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

}

Ответ 14

С Angular 8 и Bootstrap 4.2 это рабочее решение, которое я использую:

1- Сначала я создал пользовательскую директиву. Он слушает событие нажатия кнопки в раскрывающемся контейнере и переключает класс .show элемента .dropdown-menu (стандартное поведение 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- Как только ваша директива создана и зарегистрирована. Обязательно примените директиву к выпадающему элементу, как в этом примере:

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