在手动刷新之前页面无法正常显示 Angular

Page is not displaying properly until manually refresh Angular

我遇到了一个很奇怪的问题。我的 angular 申请页面显示正常。它似乎没有完全加载,当我手动 reloading/refreshing 页面时,它加载正常。

这是完整的场景。我创建了一个完美显示并按预期工作的登录页面。登录后,我导航到我的仪表板页面,该页面显示不正确,似乎加载了一半,但是当手动刷新时它工作正常。检查元素后,我发现仪表板的内容在那里,但显示不正确。控制台也没有任何错误

这是我的应用程序-routing.module.ts代码:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { MainLayoutComponent } from './main-layout/main-layout.component';

const routes: Routes = [

  { path: 'login', component: LoginComponent },
  { path: 'dashboard', component: MainLayoutComponent },
  { path: '', pathMatch: "full", redirectTo: 'dashboard' },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

这是我的 login.component.ts

declare var $: any;
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Common } from '../Common/common';
import { Router } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class LoginComponent implements OnInit {
  constructor(private httpClient: HttpClient, private router: Router) { }

  form: any;

  submitModel: any = {
    username: "",
    password: ""
  };

  ngOnInit(): void {
    this.form = $('#myloginform').parsley();

    localStorage.clear();
  }

  SubmitForm() {
    if ($("#myloginform").parsley().validate()) {
      $(".preloader").show();
      this.httpClient.post<any>(Common.APIUrl + "login", this.submitModel, { withCredentials: true }).subscribe(
        {
          next: data => {
            console.log(data);
            localStorage.setItem("token", data.result);
            this.router.navigate(['dashboard']);
          },
          error: error => {
            console.error(error);
          },
          complete: function () {
            console.log("complete");
            $(".preloader").hide();
          }
        }
      );
    }
  }
}

这是我的主要-layout.component.ts

declare var $: any;
import { HttpClient } from '@angular/common/http';
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { Router } from '@angular/router';
import { Common } from '../Common/common';

@Component({
  selector: 'app-main-layout',
  templateUrl: './main-layout.component.html',
  styleUrls: ['./main-layout.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class MainLayoutComponent implements OnInit {
  constructor(private httpClient: HttpClient, private router: Router) { }

  ngOnInit(): void {
    console.log("MainLayoutComponent - on init called")
  }


  Logout() {
    $(".preloader").show();
    this.httpClient.get<any>(Common.APIUrl + "logout", { withCredentials: true }).subscribe(
      {
        next: data => {
          localStorage.clear();
          this.router.navigate(['login']);
        },
        error: error => {
          console.error(error);
        },
        complete: function () {
          $(".preloader").hide();
        }
      }
    );
  }
}

目前面临的情况是:

预期结果:

附加信息:当我注销时,它会正确导航到登录页面。我在我的索引 html 页面中添加了 jQuery/Bootstrap 的所有引用 + 附加插件。

我是 angular 的新手,这是我在 Whosebug 中的第一个问题。请原谅我,如果我不能解释得更好。提前致谢

我从仪表板中删除了内容,只添加了一个

标签。它正在显示

Index.html

<!DOCTYPE html>
<html dir="ltr" lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <!-- Tell the browser to be responsive to screen width -->
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="robots" content="noindex,nofollow">
  <base href="/">
  <title>Employee App</title>
  <!-- Favicon icon -->
  <link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon.png">
  <!-- Custom CSS -->
  <link href="assets/dist/css/style.min.css" rel="stylesheet">
  <link href="assets/dist/css/style.extended.css" rel="stylesheet">
</head>
<body>

  <app-root></app-root>

  <script src="assets/libs/jquery/dist/jquery.min.js"></script>
  <!-- Bootstrap tether Core JavaScript -->
  <script src="assets/libs/popper.js/dist/umd/popper.min.js"></script>
  <script src="assets/libs/bootstrap/dist/js/bootstrap.min.js"></script>
  <!--Parsley -->
  <script src="assets/extra-libs/parsley/parsley.js"></script>
  <!-- apps -->
  <script src="assets/dist/js/app.min.js"></script>
  <script src="assets/dist/js/app.init.js"></script>
  <script src="assets/dist/js/app-style-switcher.js"></script>
  <!-- slimscrollbar scrollbar JavaScript -->
  <script src="assets/libs/perfect-scrollbar/dist/perfect-scrollbar.jquery.min.js"></script>
  <script src="assets/libs/jquery-sparkline/jquery.sparkline.min.js"></script>
  <!--Wave Effects -->
  <script src="assets/dist/js/waves.js"></script>
  <!--Menu sidebar -->
  <script src="assets/dist/js/sidebarmenu.js"></script>
  <!--Custom JavaScript -->
  <script src="assets/dist/js/feather.min.js"></script>
  <script src="assets/dist/js/custom.min.js"></script>
</body>
</html>

MainLayout.component.html

<div id="main-wrapper">
  <header class="topbar">
    <nav class="navbar top-navbar navbar-expand-md navbar-dark">
      <div class="navbar-header">
        <a class="nav-toggler waves-effect waves-light d-block d-md-none" href=""><i class="ti-menu ti-close"></i></a>
        <a class="navbar-brand" href="">
          <b class="logo-icon">
            <img src="../assets/images/logo-icon.png" alt="homepage" class="dark-logo" />
            <img src="../assets/images/logo-light-icon.png" alt="homepage" class="light-logo" />
          </b>
          <span class="logo-text">
            <img src="../assets/images/logo-text.png" alt="homepage" class="dark-logo" />
            <img src="../assets/images/logo-light-text.png" class="light-logo" alt="homepage" />
          </span>
        </a>
        <a class="topbartoggler d-block d-md-none waves-effect waves-light" href="" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><i class="ti-more"></i></a>
      </div>
      <div class="navbar-collapse collapse" id="navbarSupportedContent">
        <ul class="navbar-nav mr-auto">
          <li class="nav-item d-none d-md-block"><a class="nav-link sidebartoggler waves-effect waves-light" href="" data-sidebartype="mini-sidebar"><i class="icon-arrow-left-circle"></i></a></li>
        </ul>
        <ul class="navbar-nav">
          <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle text-muted waves-effect waves-dark pro-pic" href="" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><img src="../assets/images/users/1.jpg" alt="user" class="rounded-circle" width="31"></a>
            <div class="dropdown-menu dropdown-menu-right user-dd animated flipInY">
              <div class="d-flex no-block align-items-center p-3 mb-2 border-bottom">
                <div class=""><img src="../assets/images/users/1.jpg" alt="user" class="rounded" width="80"></div>
                <div class="ml-2">
                  <h4 class="mb-0">Steave Jobs</h4>
                  <p class=" mb-0">varun@gmail.com</p>
                  <a href="profile.html" class="btn btn-rounded btn-danger btn-sm">View Profile</a>
                </div>
              </div>
              <a class="dropdown-item" href="" (click)="Logout()"><i class="fa fa-power-off mr-1 ml-1"></i> Logout</a>
            </div>
          </li>
        </ul>
      </div>
    </nav>
  </header>

  <aside class="left-sidebar">
    <div class="scroll-sidebar">
      <nav class="sidebar-nav">
        <ul id="sidebarnav">
          <li class="nav-small-cap"><i class="mdi mdi-dots-horizontal"></i> <span class="hide-menu">Personal</span></li>
          <li class="sidebar-item">
            <a href="" class="sidebar-link waves-effect waves-dark" aria-expanded="false"><i data-feather="link" class="feather-icon"></i><span class="hide-menu">Sample Link</span></a>
          </li>
          <li class="sidebar-item">
            <a class="sidebar-link has-arrow waves-effect waves-dark" href="" aria-expanded="false"><i data-feather="map" class="feather-icon"></i><span class="hide-menu">Sample Link</span></a>
            <ul aria-expanded="false" class="collapse  first-level">
              <li class="sidebar-item"><a href="map-google.html" class="sidebar-link"><i class="mdi mdi-adjust"></i><span class="hide-menu">Google Maps</span></a></li>
              <li class="sidebar-item"><a href="map-vector.html" class="sidebar-link"><i class="mdi mdi-adjust"></i><span class="hide-menu">Vector Maps</span></a></li>
            </ul>
          </li>
          <li class="sidebar-item">
            <a class="sidebar-link has-arrow waves-effect waves-dark" href="" aria-expanded="false"><i data-feather="git-pull-request" class="feather-icon"></i><span class="hide-menu">Multi level dd</span></a>
            <ul aria-expanded="false" class="collapse first-level">
              <li class="sidebar-item"><a href="" class="sidebar-link"><i class="mdi mdi-octagram"></i><span class="hide-menu">item 1.1</span></a></li>
              <li class="sidebar-item"><a href="" class="sidebar-link"><i class="mdi mdi-octagram"></i><span class="hide-menu">item 1.2</span></a></li>
              <li class="sidebar-item">
                <a class="has-arrow sidebar-link" href="" aria-expanded="false"><i class="mdi mdi-playlist-plus"></i> <span class="hide-menu">Menu 1.3</span></a>
                <ul aria-expanded="false" class="collapse second-level">
                  <li class="sidebar-item"><a href="" class="sidebar-link"><i class="mdi mdi-octagram"></i><span class="hide-menu"> item 1.3.1</span></a></li>
                  <li class="sidebar-item"><a href="" class="sidebar-link"><i class="mdi mdi-octagram"></i><span class="hide-menu"> item 1.3.2</span></a></li>
                  <li class="sidebar-item"><a href="" class="sidebar-link"><i class="mdi mdi-octagram"></i><span class="hide-menu"> item 1.3.3</span></a></li>
                  <li class="sidebar-item"><a href="" class="sidebar-link"><i class="mdi mdi-octagram"></i><span class="hide-menu"> item 1.3.4</span></a></li>
                </ul>
              </li>
              <li class="sidebar-item"><a href="" class="sidebar-link"><i class="mdi mdi-playlist-check"></i><span class="hide-menu"> item 1.4</span></a></li>
            </ul>
          </li>
        </ul>
      </nav>
    </div>
    <div class="sidebar-footer">
      <a href="" class="link" data-toggle="tooltip" title="Settings"><i class="ti-settings"></i></a>
      <a href="" class="link" data-toggle="tooltip" title="Email"><i class="mdi mdi-gmail"></i></a>
      <a href="" class="link" data-toggle="tooltip" title="Logout"><i class="mdi mdi-power"></i></a>
    </div>
  </aside>
  <div class="page-wrapper">

    <!--<router-outlet></router-outlet>-->

    <footer class="footer">
      © 2020 Monster Admin by wrappixel.com
    </footer>
  </div>
</div>

你在哪里 localStorage.getItem("token")?你在哪里使用?

如果您在 MainLayoutComponent 中使用,我想您会进入该组件的 ngOnInit。

如果您在 main.component 中的其他组件中使用了 <router-outlet>- 已经加载了您 需要向 Angular 表明localStorage 已更改。通常,您可以使用一项服务的主题。那是:

假设您有一项服务。由于您应该在服务中而不是在组件中进行所有调用,因此您可以拥有类似

的服务
@Injectable({
  providedIn: 'root',
})
export class LoginService {
  login$:Subject<bool>=new Subject<bool>()
  constructor(private httpClient:HttpClient) { }

  login(model:any)
  {
      return this.httpClient.post<any>(Common.APIUrl + "login", model, { withCredentials: true })
       .pipe(tap(()=>{
            this.login$.next(true); //<--makes subject "next"
       })
      );
     
  }
  logout()
  {
    return this.httpClient.get<any>(Common.APIUrl + "logout", { withCredentials: true })
       .pipe(tap(()=>{
            this.login$.next(false); //<--makes subject "next"
       })
    )
  }

看到函数 return 一个可观察的 - 调用你的 API-

当您订阅登录服务时 - 将 httpClient.get 替换为 this.loginService.login() 和 this.loginService.logout()-

  SubmitForm() {
    if ($("#myloginform").parsley().validate()) {
      $(".preloader").show();
      this.loginService.login(this.submitModel)
        .subscribe(
         {
            ..your code..
         })
      );
    }
  }

Logout() {
    $(".preloader").show();
    this.loginService.logOut().subscribe(
      {
         ...your code
      }
    );
  }

看到了吧,“主题”变了。所以在你需要token信息的组件中你可以订阅这个主题并阅读token

this.loginService.login$.subscribe((res:boolean)=>{
    ..make something to updte the "login"
})

谢谢@The Head Rush 给我指明了正确的方向。我正在使用并非为 Angular 设计的 bootstrap 主题。在挖掘了一些 Theme js 文件之后,我看到一些代码使用 jQuery 代码根据主题选择在运行时实现一些 类 。我只是再次调用了它的主题设置功能,它的工作原理。在我的 mainlayout 组件初始化函数中,我添加了这段代码

  ngOnInit(): void {
    $("#main-wrapper").AdminSettings();
  }