【问题标题】:Why do the Bootstrap 4 elements reload entire Angular 7 application?为什么 Bootstrap 4 元素会重新加载整个 Angular 7 应用程序?
【发布时间】:2019-07-11 21:23:45
【问题描述】:

我正在使用 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>

【问题讨论】:

  • 您如何导航到catalogo/lista 路线?您是否在页面中使用 [routerLink] 指令?另外(只是为了仔细检查),您的侧边栏是否在您的 &lt;router-outlet&gt; 元素之外?
  • 是的,我正在使用 [routerLink] 来访问我的路由,并且侧边栏在 之外,只有当我在浏览器中输入完整的 url 时出现问题,例如 @987654324 @ 或 localhost:4200/home。如果我进入路由localhost:4200,或任何其他不存在的路由,我将被重定向到家并且应用程序运行良好
  • 编辑:刚刚看到你的编辑,我明白现在发生了什么更好!输入直接 URL 时页面是否无法正常加载?还是其他组件加载不正确?
  • 页面和组件加载良好,但是当我单击显示/隐藏侧边栏的按钮(我的问题开头的 元素)时,页面被重新加载(尝试去到 # in href),而不是显示/隐藏侧边栏
  • 由于href="#" 的存在,点击a 元素将始终触发路由操作。删除 href 是否会破坏引导操作?如果是这样,您几乎可以肯定在 Angular 中重新创建它。如果您提供一些通用组件代码(显示包含侧边栏和a 元素的组件),我可以向您展示如何完成此操作!

标签: css angular web bootstrap-4


【解决方案1】:

一般来说,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 过渡)。

【讨论】:

  • 非常感谢。问题是原始引导模板中的 javascript/jquery 代码,它试图访问尚未加载的元素。现在,将其转换为 Angular 组件和服务,我的应用程序运行良好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-09
  • 1970-01-01
  • 1970-01-01
  • 2014-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多