首页 > 解决方案 > 为什么 Bootstrap 4 元素会重新加载整个 Angular 7 应用程序?

问题描述

我正在使用 bootstrap 4 和 angular 7,我有以下元素,它的功能是隐藏/显示侧边栏。

<a
  class="app-sidebar__toggle"
  href="#"
  data-toggle="sidebar"
  aria-label="Hide Sidebar"
></a>

问题是当我进入特定路线时,这会重新加载所有页面。这些是我在 app-routing.module.ts 中的路线

const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: 'catalogo/lista', component: CatalogoListaComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' }
];

因此,如果我输入http://localhost:4200/home,就会发生错误,但如果我输入任何其他路由(我的默认空路由将重定向到 /home),例如http://localhost: 4200http://localhost:4200/a_route_that_not_exists,我被重定向到 /home (如预期的那样),显示/隐藏侧边栏的按钮效果很好。

我希望清楚我的问题,我希望你能帮助我很多。

编辑:我的应用程序的更多代码......

这是我的 app.component.html:

<app-header></app-header>

<app-sidebar></app-sidebar>

<div class="app-content">
  <app-title [titulo]="titulo" [icono]="icono [breadcrumbs]="breadcrumbs"></app-title>
  <router-outlet></router-outlet>
</div>

这是我的 header.component.html(我使用链接显示/隐藏侧边栏):

<header class="app-header">
  <a class="app-header__logo" href="index.html">Vali</a>
  <!-- Sidebar toggle button-->
  <a
    class="app-sidebar__toggle"
    href="#"
    data-toggle="sidebar"
    aria-label="Hide Sidebar"
  ></a>
  <p>.... more html</p>
</header>

这是我的 sidebar.component.html:

<div class="app-sidebar__overlay" data-toggle="sidebar"></div>
<aside class="app-sidebar">
  <div class="app-sidebar__user">
    <img
      class="app-sidebar__user-avatar"
      src="https://s3.amazonaws.com/uifaces/faces/twitter/jsa/48.jpg"
      alt="User Image"
    />
    <div>
      <p class="app-sidebar__user-name">John Doe</p>
      <p class="app-sidebar__user-designation">Frontend Developer</p>
    </div>
  </div>
  <ul class="app-menu">
    <li>
      <a class="app-menu__item" [routerLink]="['/home']">
        <i class="app-menu__icon fa fa-home"></i>
        <span class="app-menu__label">Inicio</span>
      </a>
    </li>
    more menu elements...
  <ul>
</aside>

标签: cssangularwebbootstrap-4

解决方案


通常 Bootstrap 中的许多 Popper/JS 元素在 Angular 中都不能开箱即用;Angular 提供了一种非常可靠的方式来处理诸如 sidenav 之类的元素。

由于要用于切换 sidenav 的元素与 sidenav 不存在于同一组件中,因此您可以设置一个处理 sidenav 状态的基本服务。创建 sidenav 服务(在项目根目录的控制台中运行):

ng g s sidenav

然后在生成的sidenav.service.ts中:

import {Injectable} from '@angular/core';
import {BehaviorSubject} from 'rxjs';

@Injectable()
export class SidenavService {
  public isOpen: boolean = false;
  public toggleChange: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

  constructor() {}

  public toggle(): void {
    this.isOpen = !this.isOpen;
    this.toggleChange.next(this.isOpen);
  }
}

在你的header.component.html你可以修改将显示/隐藏侧边栏的可点击元素:

<a
  class="app-sidebar__toggle"
  aria-label="Hide Sidebar"
  (click)="toggleSidebar()"
></a>

在您的header.component.ts文件中,您可以设置在刚刚设置的服务toggleSidebar()中运行该功能:toggle()

import {SidenavService} from "[wherever your service is located]";


@Component({ /*...*/ })
export class HeaderComponent {

  constructor(private sidenavService: SidenavService)

  toggleSidebar(): void {
    this.sidenavService.toggle();
  }

}

然后,您可以(在您的应用程序组件或侧边栏组件中)设置对切换的反应:

//assuming you're in sidebar.component.ts
import {SidenavService} from "[wherever your service is located]";
import {OnInit, OnDestroy} from "@angular/core";
import {Subscription} from "rxjs";

@Component({ /*...*/ })
export class SidebarComponent implement OnInit, OnDestroy {
  isOpen: boolean;
  sidenavSubscription: Subscription;

  constructor(private sidenavService: SidenavService) {}

  ngOnInit() {
    this.sidenavSubscription = this.sidenavService.toggleChange.subscribe(isOpenChange => {
      this.isOpen = isOpenChange;
    });
  }

  ngOnDestroy() {
    this.sidenavSubscription.unsubscribe();
  }
}

isOpen然后,您可以以不同的方式在侧边栏组件中使用该变量来控制侧边栏活动。示例包括使用[ngClass]指令:

<!--in your header component-->
<header [ngClass]={'active': isOpen, 'inactive': !isOpen} >
</header>

或者,您可以使用角度动画构建一些东西来为侧边栏设置动画(使用ngIf:enter/:leave过渡)。


推荐阅读