在 Angular 2 路由更改时强制折叠 Bootstrap 4 导航栏

13

我希望以正确的方式在Angular 2中实现以下类似的内容:

$('.collapse').hide();

在Angular 2中应该如何处理这个问题?我只需要使用原生JavaScript吗?还是应该使用内置的Angular方法?

编辑:让我为我的特定情况添加一些背景。

我有一个带有可折叠导航的Bootstrap 4导航栏。如果你下拉导航,然后点击一个链接,导航栏不会像你期望的那样消失

我希望当你点击任何链接时,导航栏都会回到折叠状态。

以下是我的导航栏标记:

<nav class="navbar navbar-toggleable-md navbar-inverse bg-inverse fixed-top">

  <button class="navbar-toggler navbar-toggler-right"
          type="button"
          data-toggle="collapse"
          data-target="#foodie-navbar"
          aria-controls="foodie-navbar"
          aria-expanded="false"
          aria-label="Toggle navigation">

    <span class="navbar-toggler-icon"></span>
  </button>

  <a class="navbar-brand" routerLink="/">Foodie</a>

  <div class="collapse navbar-collapse" id="foodie-navbar">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item" *ngIf="auth.authenticated()">
        <a class="nav-link" [routerLink]="['/places']">Places</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" routerLink="" (click)="auth.login()" *ngIf="!auth.authenticated()">Log In</a>
        <a class="nav-link" routerLink="" (click)="auth.logout()" *ngIf="auth.authenticated()">Log Out</a>
      </li>
    </ul>
  </div>
</nav>

<div class="container">
  <router-outlet></router-outlet>
</div>

这是我的AppComponent的样子:

import { Component } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { Auth } from './auth.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [Auth]
})
export class AppComponent {
  constructor(private auth: Auth, private router: Router) {
    router.events.subscribe(val => {
      if (val instanceof NavigationEnd) {
        // This is when the hiding should happen.
      }
    })
  }
}

顺便说一下,现在我仔细看了一下,如果我在控制台上执行$('.collapse').hide();,然后再次点击汉堡菜单,它不起作用。所以也许我需要完全不同的解决方案。

编辑:有人将此问题标记为ng2-bootstrap问题的副本。我的问题/答案与ng2-bootstrap无关,因此我不认为这是一个副本。


可能是在ng2-bootstrap中构建移动导航栏的方法?的重复问题。 - bergben
我不这么认为。那个问题和答案只适用于ng2-bootstrap,如果我没记错的话,不适用于这个问题。 - Jason Swett
4个回答

27

通过触发导航栏切换按钮的点击事件,我实现了自己想要的目标。

在下面的两段代码中,最重要的可能是注意collapseNav()函数。

这是我的组件代码:

import { Component, ViewChild, ElementRef } from '@angular/core';
import { Auth } from './auth.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [Auth]
})
export class AppComponent {
  @ViewChild('navbarToggler') navbarToggler:ElementRef;

  constructor(private auth: Auth) {}

  navBarTogglerIsVisible() {
    return this.navbarToggler.nativeElement.offsetParent !== null;
  }

  collapseNav() {
    if (this.navBarTogglerIsVisible()) {
      this.navbarToggler.nativeElement.click();
    }
  }
}

这是我的标记

<nav class="navbar navbar-toggleable-md navbar-inverse bg-inverse fixed-top">

  <button #navbarToggler class="navbar-toggler navbar-toggler-right"
          type="button"
          data-toggle="collapse"
          data-target="#foodie-navbar"
          aria-controls="foodie-navbar"
          aria-expanded="false"
          aria-label="Toggle navigation">

    <span class="navbar-toggler-icon"></span>
  </button>

  <a class="navbar-brand" routerLink="/">Foodie</a>

  <div class="collapse navbar-collapse" id="foodie-navbar">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item" *ngIf="auth.authenticated()">
        <a (click)="collapseNav()" class="nav-link" [routerLink]="['/places']">Places</a>
      </li>
      <li class="nav-item">
        <a (click)="collapseNav(); auth.login()" class="nav-link" routerLink="" *ngIf="!auth.authenticated()">Log In</a>
        <a (click)="collapseNav(); auth.logout()" class="nav-link" routerLink="" *ngIf="auth.authenticated()">Log Out</a>
      </li>
    </ul>
  </div>
</nav>

<div class="container">
  <router-outlet></router-outlet>
</div>

2
这是我成功的做法。
  1. 打开 app.component.ts

  2. 导入 Router 和 NavigationEnd:

    import { Router, NavigationEnd } from '@angular/router';

  3. 在 import 下面插入以下内容以访问 JQuery:

    declare var $: any;

  4. 在构造函数中添加以下内容:

    private router: Router

  5. 在 ngOnInit() 中添加以下内容:

    this.router.events.subscribe((evt) => { if (!(evt instanceof NavigationEnd)) { return; } // 滚动到页面顶部 window.scrollTo(0, 0); // 这将关闭顶部导航栏 $(document).click((event) => { const click = $(event.target); const _open = $('.navbar-collapse').hasClass('show'); if (_open === true && !click.hasClass('navbar-toggler')) { $('.navbar-toggler').click(); } }); });

我正在使用 NG 10 和 bootstrap 5,但我知道它适用于之前版本的 NG 和 Bootstrap 4.5.x。


1
我有另一个解决方案
从这篇文章中获得了一些灵感,也进行了一些研究。其中一篇我读过的文章是: https://medium.com/@tiboprea/build-a-responsive-bootstrap-4-navbar-in-angular-5-without-jquery-c59ad35b007 因此,在这个解决方案中,可以通过单击切换按钮来折叠,也可以在路由更改时折叠。

//nav.component.html

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
 <a class="navbar-brand" href="#">
  Brand
 </a>

<button class="navbar-toggler" type="button" (click)="toggleNavbar()">
   <span class="navbar-toggler-icon"></span>
</button>

<div class="collapse navbar-collapse" [ngClass]="{ 'show': navbarOpen }">
  <ul class="navbar-nav mr-auto">
   <li class="nav-item">
    <a class="nav-link" href="#">Item 1</a>
   </li>

   <li class="nav-item">
    <a class="nav-link" href="#">Item 2</a>
   </li>
  </ul>
 </div>
</nav>

//nav.component.ts

import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';

export class NavComponent implements OnInit {

constructor(private router: Router) {}


ngOnInit(): void {

  this.router.events
    .pipe(filter(evt => evt instanceof NavigationEnd))  
    .subscribe((evt: NavigationEnd) => {
      this.navbarOpen = false;
    });
  }

  toggleNavbar() {
    this.navbarOpen = !this.navbarOpen;
  }
 }

0

Bootstrap具有内置的JavaScript,可在用户单击汉堡菜单时打开和关闭菜单。这由data-bs-toggledata-bs-target处理,也可以应用于菜单链接:

<a class="nav-link" 
  [routerLink]="['/']" href="#" 
  data-bs-toggle="collapse" 
  data-bs-target="#navbarNavDropdown"
>Home</a>

在 Bootstrap 5 + Angular 15 中进行了测试。使用 npm install --save bootstrap@v5.2.3 @types/bootstrap 安装了 Bootstrap。在 Angular 中不需要进一步的配置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接